Détection d'à-coups dans l'UI

Android affiche l'interface utilisateur en générant une frame à partir de votre application et en l'affichant à l'écran. Si votre application souffre d'un rendu de l'interface utilisateur lent, alors le système est obligé de sauter des frames. Dans ce cas, l'utilisateur perçoit un scintillement récurrent à l'écran, appelé à-coup.

Les à-coups sont généralement dûs à une décélération ou un blocage des appels asynchrones sur le thread UI (dans la plupart des applications, il s'agit du thread principal). Vous pouvez utiliser les traces système pour identifier l'origine du problème.

Détecter les à-coups sur Android 12 ou version ultérieure

Pour les appareils équipés d'Android 12 (niveau d'API 31) ou version ultérieure, une trace capturée est affichée dans la ligne Frames saccadées sous le volet Display du Profileur de processeur.

Pour détecter les à-coups, procédez comme suit :

  1. Dans Android Studio, sélectionnez View > Tool Windows > Profiler Vue > Fenêtres d'outils > Profileur ou cliquez sur Profile (Profil) dans la barre d'outils.

    Si vous y êtes invité par la boîte de dialogue Select Deployment Target (Sélectionner une cible de déploiement), choisissez l'appareil sur lequel déployer votre application à des fins de profilage. Si vous avez connecté un appareil en USB, mais qu'il ne figure pas dans la liste, assurez-vous d'avoir activé le débogage USB.

  2. Cliquez n'importe où dans la chronologie du CPU pour ouvrir le Profileur de processeur.

  3. Sélectionnez System Trace (Trace système) dans le menu de configuration du Profileur de processeur, puis cliquez sur Save (Enregistrer). Une fois que vous avez terminé d'interagir avec votre application, cliquez sur Arrêter.

  4. La piste Janky frames (Frames saccadés) doit s'afficher sous Display (Affichage). Par défaut, le profileur n'affiche que les frames irréguliers comme candidats à une enquête. Dans chaque frame saccadé, la partie rouge met en évidence la durée écoulée entre l'affichage du frame et son délai d'affichage. Capture d'écran de la ligne "Janky frames" (Frames saccadés)

  5. Une fois que vous avez trouvé une frame saccadée, cliquez dessus. Vous pouvez également appuyer sur M pour régler le zoom afin de vous focaliser sur le frame sélectionné. Les événements pertinents sont mis en évidence dans ces threads : le thread principal, RenderThread et GPU completion.Capture d'écran du profileur montrant les frames saccadés et les threads principaux

  6. Vous pouvez aussi afficher tous les frames ou une répartition du délai d'affichage en cochant respectivement les cases All Frames (Tous les frames) et Lifecycle (Cycle de vie). Capture d'écran du profileur comme ci-dessus, mais avec les cases Toutes les frames et Cycle de vie cochées

Détecter les à-coups sur Android 11

Pour les appareils équipés d'Android 11 (niveau d'API 30), une trace capturée est affichée dans la section Cycle de vie de la frame du Profileur de processeur.

Section Cycle de vie de la frame avec les différentes sections

La section Cycle de vie de la frame contient le nom de la couche et quatre lignes. Chaque ligne représente une étape du pipeline de rendu des frames. Les éléments du Cycle de vie de la frame sont les suivants :

  1. Cycle de vie de la frame (nom de la couche) : le titre de la section contient le nom de la couche entre parenthèses. Une couche est une unité de composition unique.
  2. Application : cette ligne indique le moment où le tampon a été retiré de la file d'attente par l'application jusqu'au moment où il a été remis dans la file d'attente. Cela correspond généralement aux événements de trace dans RenderThread.
  3. Attente du GPU : cette ligne indique la durée pendant laquelle le tampon a appartenu au GPU. Il s'agit du temps entre le moment où le tampon est envoyé au GPU et le moment où le GPU a fini de travailler sur le tampon. Cela ne signifie pas que le GPU ne fonctionnait que sur ce tampon pendant cette période. Pour obtenir des informations détaillées sur le fonctionnement du GPU au cours d'une période donnée, vous pouvez utiliser Android GPU Inspector.
  4. Composition : cette ligne indique le temps écoulé entre le moment où SurfaceFlinger est appliqué au tampon et l'envoie pour composition, jusqu'à l'envoi du tampon à l'écran.
  5. Frames affichées à l'écran : cette ligne indique la durée d'affichage de la frame sur l'écran.

La section Cycle de vie de la frame illustre la façon dont un tampon d'image se déplace entre les différentes étapes du pipeline du rendu. Les frames sont codées par couleur afin de faciliter le suivi d'une frame en particulier.

Android Studio affiche également toutes les frames dans la trace sous forme de tableau dans l'onglet Toutes les frames.

Un tableau de toutes les frames de la trace dans l'onglet Toutes les frames

Les colonnes Frame #, Application, Wait for GPU (Attente du GPU) et Composition représentent les mêmes données que les lignes dans la section Cycle de vie du frame, comme indiqué ci-dessus. La colonne Durée de la frame représente le temps écoulé entre le lancement de l'application et l'affichage des frames sur l'écran. Il s'agit du temps nécessaire pour afficher d'un frame du début à la fin.

Vous pouvez trier le tableau des frames selon n'importe quelle colonne pour trouver rapidement la frame la plus courte ou la plus longue. Le tableau est également compatible avec les commandes de pagination qui vous aident à parcourir des centaines de frames.

Pour détecter et analyser les à-coups sur Android 11, procédez comme suit :

  1. Triez la table Toutes les frames par ordre décroissant sur la colonne Application afin que les frames les plus longues apparaissent en premier.

    Colonne Application triée par ordre décroissant

  2. Identifiez les frames les plus longues et sélectionnez la ligne du tableau. Un zoom avant est effectué sur l'image sélectionnée dans la vue chronologique située à gauche.

    Vue chronologique à côté du tableau des frames

  3. Recherchez les threads pertinents dans les sections Cycle de vie de la frame et Threads.

    Sections Cycle de vie de la frame et Threads

Détecter les à-coups sur Android 10 ou version antérieure

Pour les appareils équipés d'Android 10 (niveau d'API 29) ou version antérieure, les informations pertinentes sur le pipeline des graphismes du système d'exploitation sont affichées dans une seule section de la trace système du Profileur de processeur appelée Display.

Fenêtre d'affichage de l'interface utilisateur

  • Frames : cette section présente le thread UI et les événements de trace RenderThread dans votre application. Les événements de plus de 16 ms sont colorés en rouge pour mettre en évidence les éventuels à-coups, car ils dépassent le délai d'affichage de 60 frames par seconde (FPS).
  • SurfaceFlinger : cette section indique à quel moment l'outil SurfaceFlinger traite les tampons de frame. SurfaceFlinger est un processus système chargé d'envoyer des tampons à afficher.
  • VSYNC : cette section affiche le VSYNC, un signal qui synchronise le pipeline d'affichage. Sur la ligne est affichée le signal VSYNC de l'application, qui apparaît lorsque votre application commence trop tard. En général, cela se produit parce que le thread UI est occupé. Un scintillement visible s'affiche à l'écran lors d'une animation et augmente la latence d'entrée jusqu'à la fin de l'animation ou du défilement. Cela est particulièrement important à prendre en compte pour les écrans à fréquence d'actualisation élevée, car ils peuvent se produire plus de 60 fois par seconde ou à un rythme variable.
  • BufferQueue : cette section indique le nombre de tampons de frame en file d'attente et en attente de leur utilisation par SurfaceFlinger. Pour les applications déployées sur des appareils équipés d'Android 9 (niveau d'API 28) ou version ultérieure, ce canal affiche le nombre de tampons de la surface de l'application BufferQueue (0, 1 ou 2). BufferQueue peut vous aider à comprendre l'état des tampons d'image lorsqu'ils se déplacent entre les composants graphiques Android. Par exemple, la valeur 2 signifie que l'application est actuellement mise en mémoire tampon trois fois, ce qui entraîne une latence d'entrée accrue.

La section Display fournit des informations utiles pour détecter les à-coups (par exemple, lorsque le thread UI ou RenderThread prend plus de 16 ms). Pour en connaître les causes exactes, vous pouvez examiner la section Threads, qui indique les threads en rapport avec l'affichage dans l'interface utilisateur.

Section Threads sous Display

Dans la figure ci-dessus, la section Threads affiche le thread UI (java.com.google.samples.apps.iosched), RenderThread et le thread GPU completion. Il s'agit des threads en rapport avec l'affichage de l'interface utilisateur et qui peuvent contribuer aux à-coups.

Pour détecter les à-coups sous Android 10 ou version antérieure, procédez comme suit :

  1. Consultez la ligne Frames dans Display. Les frames en rouge sont de bons candidats pour une enquête.

    Section Frames sous Display

  2. Une fois que vous avez trouvé une frame sacadée, faites un zoom avant en appuyant sur W ou en faisant défiler la molette de la souris tout en maintenant la touche Ctrl enfoncée (Commande sur macOS). Continuez à zoomer jusqu'à ce que les événements de trace commencent à s'afficher dans le thread UI et RenderThread.

    Événements de trace dans le thread UI et RenderThread

    Dans la figure ci-dessus, Choreographer#doFrame montre à quel moment le thread UI appelle Choreographer pour coordonner l'animation, la mise en page, le dessin et les processus associés. DrawFrames montre lorsque RenderThread se forme et envoie des commandes de dessin réelles au GPU.

  3. Si vous constatez un événement de trace particulièrement long, vous pouvez faire un zoom avant et découvrir ce qui a contribué à l'affichage lent. La figure ci-dessus montre inflate dans le thread UI, ce qui signifie que l'application perd du temps à gonfler la mise en page. Lorsque vous zoomez sur l'un des événements inflate, vous pouvez savoir exactement combien de temps prend chaque composant d'UI, comme indiqué ci-dessous.

    Menu affichant la durée précise d'un composant UI

En savoir plus

Pour en savoir plus sur la façon de réduire les à-coups, consultez la section Principales sources d'à-coups.