1. Introduction
Dernière mise à jour : 11/03/2021
Pourquoi devons-nous mesurer les performances des vues ?
Les vues sont un élément clé des applications Android qui affectent directement l'expérience utilisateur. Par exemple, votre activité ou fragment contient l'UI qui contient les composants View avec lesquels les utilisateurs interagissent. Les utilisateurs ne peuvent pas voir l'intégralité du contenu de l'UI tant qu'il n'est pas entièrement affiché à l'écran. Les écrans lents et figés nuisent directement à l'interaction des utilisateurs avec votre application et créent une mauvaise expérience utilisateur.
Firebase Performance Monitoring ne fournit-il pas ces métriques de performances prêtes à l'emploi ?
Firebase Performance Monitoring capture automatiquement certaines données de performances prêtes à l'emploi, comme le temps de démarrage de votre application (c'est-à-dire le temps de chargement de votre première activité uniquement) et les performances de rendu d'écran (c'est-à-dire les frames lents et figés pour les activités, mais pas pour les fragments). Toutefois, les applications sectorielles ne comportent généralement pas beaucoup d'activités, mais plutôt une activité et plusieurs fragments. De plus, de nombreuses applications implémentent généralement leurs propres vues personnalisées pour les cas d'utilisation plus complexes. Il est donc souvent utile de comprendre comment mesurer le temps de chargement et les performances de rendu d'écran des activités et des fragments en instrumentant des traces de code personnalisées dans votre application. Vous pouvez facilement étendre cet atelier de programmation pour mesurer les performances des composants de vue personnalisés.
Points abordés
- Ajouter Firebase Performance Monitoring à une application Android
- Comprendre le chargement d'une activité ou d'un fragment
- Instrumenter des traces de code personnalisé pour mesurer le temps de chargement d'une activité ou d'un fragment
- Comprendre le rendu d'écran et ce qu'est un frame lent/figé
- Instrumenter des traces de code personnalisé avec des métriques pour enregistrer les écrans lents/figés
- Afficher les métriques collectées dans la console Firebase
Prérequis
- Android Studio version 4.0 ou ultérieure
- Un appareil/émulateur Android
- Java version 8 ou ultérieure
2. Configuration
Obtenir le code
Exécutez les commandes suivantes pour cloner l'exemple de code de cet atelier de programmation. Un dossier nommé codelab-measure-android-view-performance
sera créé sur votre machine :
$ git clone https://github.com/FirebaseExtended/codelab-measure-android-view-performance.git
$ cd codelab-measure-android-view-performance
Si vous n'avez pas git sur votre ordinateur, vous pouvez également télécharger le code directement depuis GitHub.
Importez le projet measure-view-performance-start
dans Android Studio. Vous verrez probablement des erreurs de compilation ou peut-être un avertissement concernant un fichier google-services.json
manquant. Nous corrigerons cela dans la section suivante de cette étape.
Dans cet atelier de programmation, nous allons utiliser le plug-in Firebase Assistant pour enregistrer notre application Android dans un projet Firebase et ajouter les fichiers de configuration, plug-ins et dépendances Firebase nécessaires à notre projet Android, le tout depuis Android Studio !
Associer votre application à Firebase
- Accédez à Android Studio/Aide > Rechercher les mises à jour pour vous assurer d'utiliser les dernières versions d'Android Studio et de l'assistant Firebase.
- Sélectionnez Tools > Firebase (Outils > Firebase) pour ouvrir le volet Assistant.
- Sélectionnez Performance Monitoring pour l'ajouter à votre application, puis cliquez sur Premiers pas avec Performance Monitoring.
- Cliquez sur le bouton pour créer un projet, puis saisissez un nom (par exemple,
Measure Performance Codelab
). - Cliquez sur Continuer.
- Si vous y êtes invité, lisez et acceptez les Conditions d'utilisation de Firebase, puis cliquez sur Continuer.
- (Facultatif) Activez l'assistance IA dans la console Firebase (appelée "Gemini dans Firebase").
- Pour cet atelier de programmation, vous n'avez pas besoin de Google Analytics. Désactivez donc l'option Google Analytics.
- Vous devriez ensuite voir une boîte de dialogue vous invitant à associer votre nouvelle application Firebase à votre projet Android Studio.
- De retour dans Android Studio, dans le volet Assistant, vous devriez voir la confirmation que votre application est connectée à Firebase.
Ajouter Performance Monitoring à votre application
Dans le volet Assistant d'Android Studio, cliquez sur Add Performance Monitoring to your app (Ajouter Performance Monitoring à votre application).
Une boîte de dialogue Accepter les modifications devrait s'afficher. Android Studio devrait ensuite synchroniser votre application pour s'assurer que toutes les dépendances nécessaires ont été ajoutées.
Enfin, le message de confirmation devrait s'afficher dans le volet Assistant d'Android Studio, indiquant que toutes les dépendances sont correctement configurées.
En complément, activez la journalisation du débogage en suivant les instructions de l'étape "(Facultatif) Activer la journalisation du débogage". Les mêmes instructions sont également disponibles dans la documentation publique.
3. Exécuter l'application
Si vous avez correctement intégré votre application au SDK Performance Monitoring, le projet devrait maintenant se compiler. Dans Android Studio, cliquez sur Run > Run 'app' (Exécuter > Exécuter "app") pour compiler et exécuter l'application sur votre appareil Android/émulateur connecté.
L'application comporte deux boutons qui vous redirigent vers une activité et un fragment correspondants, comme suit :
Dans les étapes suivantes de cet atelier de programmation, vous allez apprendre à mesurer le temps de chargement et les performances d'affichage de l'écran de votre activité ou fragment.
4. Comprendre le chargement d'une activité ou d'un fragment
Dans cette étape, nous allons découvrir ce que fait le système lors du chargement d'une activité ou d'un fragment.
Comprendre le chargement d'une activité
Pour une activité, le temps de chargement est défini comme le temps écoulé entre la création de l'objet Activity et le moment où le premier frame est complètement dessiné à l'écran (c'est à ce moment-là que votre utilisateur verra l'UI complète de l'activité pour la première fois). Pour mesurer si votre application est entièrement dessinée, vous pouvez utiliser la méthode reportFullyDrawn()
pour mesurer le temps écoulé entre le lancement de l'application et l'affichage complet de toutes les ressources et hiérarchies de vues.
En règle générale, lorsque votre application appelle startActivity(Intent)
, le système effectue automatiquement les processus suivants. Chaque processus prend du temps, ce qui s'ajoute à la durée entre la création de l'activité et le moment où l'utilisateur voit l'UI de l'activité sur son écran.
Comprendre le chargement d'un fragment
Comme pour l'activité, le temps de chargement d'un fragment est défini comme le temps écoulé entre le moment où le fragment est associé à son activité hôte et le moment où le premier frame de la vue du fragment est entièrement dessiné à l'écran.
5. Mesurer le temps de chargement d'une activité
Les retards dans le premier frame peuvent nuire à l'expérience utilisateur. Il est donc important de comprendre le temps de chargement initial que vos utilisateurs rencontrent. Vous pouvez instrumenter une trace de code personnalisée pour mesurer ce temps de chargement :
- Démarrez la trace de code personnalisé (nommée
TestActivity-LoadTime
) dans la classe Activity dès que l'objet Activity est créé.
TestActivity.java
public class TestActivity extends AppCompatActivity {
// TODO (1): Start trace recording as soon as the Activity object is created.
private final Trace viewLoadTrace = FirebasePerformance.startTrace("TestActivity-LoadTime");
// ...
}
- Remplacez le rappel
onCreate()
et obtenez la vue ajoutée par la méthodesetContentView()
.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Current Activity's main View (as defined in the layout xml file) is inflated after this
setContentView(R.layout.activity_test);
// ...
// TODO (2): Get the View added by Activity's setContentView() method.
View mainView = findViewById(android.R.id.content);
// ...
}
- Nous avons inclus une implémentation de
FistDrawListener
, qui comporte deux rappels :onDrawingStart()
etonDrawingFinish()
(consultez la section suivante pour en savoir plus surFirstDrawListener
et ce qui peut affecter ses performances). EnregistrezFirstDrawListener
à la fin du rappelonCreate()
de l'activité. Vous devez arrêter votreviewLoadTrace
dans le rappelonDrawingFinish()
.
TestActivity.java
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when View drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Activity UI is completely drawn on the screen
viewLoadTrace.stop();
}
});
- Exécutez à nouveau l'application, puis filtrez le logcat avec Logging trace metric (Enregistrement de la métrique de trace). Appuyez sur le bouton
LOAD ACTIVITY
et recherchez des journaux semblables à ceux ci-dessous :
I/FirebasePerformance: Logging trace metric: TestActivity-LoadTime (duration: XXXms)
🎉 Félicitations ! Vous avez réussi à mesurer le temps de chargement d'une activité et à envoyer ces données à Firebase Performance Monitoring. Nous examinerons la métrique enregistrée dans la console Firebase plus loin dans cet atelier de programmation.
Objectif de FirstDrawListener
Dans la section ci-dessus, nous avons enregistré un FirstDrawListener
. L'objectif de FirstDrawListener
est de mesurer le moment où la première frame a commencé et fini d'être dessinée.
Il implémente ViewTreeObserver.OnDrawListener
et remplace le rappel onDraw()
qui est appelé lorsque l'arborescence de vues est sur le point d'être dessinée. Il encapsule ensuite le résultat pour fournir deux rappels utilitaires : onDrawingStart()
et onDrawingFinish()
.
Le code complet de FirstDrawListener
est disponible dans le code source de cet atelier de programmation.
6. Mesurer le temps de chargement d'un fragment
La mesure du temps de chargement d'un fragment est similaire à celle d'une activité, mais avec quelques différences mineures. Encore une fois, nous allons instrumenter une trace de code personnalisée :
- Remplacez le rappel
onAttach()
et commencez à enregistrer votrefragmentLoadTrace
. Nous allons nommer cette traceTest-Fragment-LoadTime
.
Comme expliqué dans une étape précédente, l'objet Fragment peut être créé à tout moment, mais il ne devient actif que lorsqu'il est associé à son activité hôte.
TestFragment.java
public class TestFragment extends Fragment {
// TODO (1): Declare the Trace variable.
private Trace fragmentLoadTrace;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
// TODO (2): Start trace recording as soon as the Fragment is attached to its host Activity.
fragmentLoadTrace = FirebasePerformance.startTrace("TestFragment-LoadTime");
}
- Enregistrez
FirstDrawListener
dans le rappelonViewCreated()
. Ensuite, comme dans l'exemple d'activité, arrêtez la trace dansonDrawingFinish()
.
TestFragment.java
@Override
public void onViewCreated(@NonNull View mainView, Bundle savedInstanceState) {
super.onViewCreated(mainView, savedInstanceState);
// ...
// TODO (3): Register the callback to listen for first frame rendering (see
// "OnFirstDrawCallback" in FirstDrawListener) and stop the trace when view drawing is
// finished.
FirstDrawListener.registerFirstDrawListener(mainView, new FirstDrawListener.OnFirstDrawCallback() {
@Override
public void onDrawingStart() {
// In practice you can also record this event separately
}
@Override
public void onDrawingFinish() {
// This is when the Fragment UI is completely drawn on the screen
fragmentLoadTrace.stop();
}
});
- Exécutez à nouveau l'application, puis filtrez le logcat avec Logging trace metric (Enregistrement de la métrique de trace). Appuyez sur le bouton
LOAD FRAGMENT
et recherchez des journaux semblables à ceux ci-dessous :
I/FirebasePerformance: Logging trace metric: TestFragment-LoadTime (duration: XXXms)
🎉 Félicitations ! Vous avez réussi à mesurer le temps de chargement d'un fragment et à signaler ces données à Firebase Performance Monitoring. Nous examinerons la métrique enregistrée dans la console Firebase plus loin dans cet atelier de programmation.
7. Comprendre le rendu d'écran et ce qu'est un frame lent/figé
L'affichage de l'UI est une action qui consiste à générer une frame à partir de votre application et à l'afficher à l'écran. Pour garantir une interaction fluide entre l'utilisateur et votre application, elle doit afficher des images en moins de 16 ms pour obtenir 60 images par seconde ( pourquoi 60 fps ?). Si votre application présente un problème d'affichage lent de l'UI, le système est obligé de sauter des images, de telle sorte que l'utilisateur constate un rendu saccadé dans votre application. On parle d'à-coups.
De même, les images figées sont des images de l'UI qui mettent plus de 700 ms à s'afficher. Ce délai pose problème, car votre application semble être bloquée et ne répond pas à l'entrée utilisateur pendant près d'une seconde complète alors que le cadre est en train de s'afficher.
8. Mesurer les images lentes/figées d'un fragment
Firebase Performance Monitoring capture automatiquement les frames lents/figés pour une activité (mais uniquement si elle est accélérée par le matériel). Toutefois, cette fonctionnalité n'est actuellement pas disponible pour les fragments. Les frames lents/figés d'un fragment sont définis comme les frames lents/figés pour l'ensemble de l'activité entre les rappels onFragmentAttached()
et onFragmentDetached()
dans le cycle de vie du fragment.
En nous inspirant de la classe AppStateMonitor
(qui fait partie du SDK Performance Monitoring et qui est responsable de l'enregistrement des traces d'écran pour l'activité), nous avons implémenté la classe ScreenTrace
(qui fait partie du dépôt de code source de cet atelier de programmation). La classe ScreenTrace
peut être associée au rappel de cycle de vie FragmentManager
de l'activité pour capturer les frames lents/figés. Cette classe fournit deux API publiques :
recordScreenTrace()
: démarre l'enregistrement d'une trace d'écran.sendScreenTrace()
: arrête l'enregistrement d'une trace d'écran et associe des métriques personnalisées pour enregistrer le nombre total d'images, ainsi que le nombre d'images lentes et figées.
En associant ces métriques personnalisées, les traces d'écran pour les fragments peuvent être traitées de la même manière que les traces d'écran pour une activité et peuvent être affichées avec d'autres traces de rendu d'écran dans le tableau de bord Performances de la console Firebase.
Voici comment enregistrer les traces d'écran pour votre fragment :
- Initialisez la classe
ScreenTrace
dans votre activité qui héberge le fragment.
MainActivity.java
// Declare the Fragment tag
private static final String FRAGMENT_TAG = TestFragment.class.getSimpleName();
// TODO (1): Declare the ScreenTrace variable.
private ScreenTrace screenTrace;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO (2): Initialize the ScreenTrace variable.
screenTrace = new ScreenTrace(this, FRAGMENT_TAG);
// ...
}
- Lorsque vous chargez votre fragment, enregistrez-vous pour
FragmentLifecycleCallbacks
et remplacez les rappelsonFragmentAttached()
etonFragmentDetached()
. Nous l'avons fait pour vous. Vous devez commencer à enregistrer les traces d'écran dans le rappelonFragmentAttached()
et arrêter l'enregistrement dans le rappelonFragmentDetached()
.
MainActivity.java
private final FragmentManager.FragmentLifecycleCallbacks fragmentLifecycleCallbacks =
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {
super.onFragmentAttached(fm, f, context);
// TODO (3): Start recording the screen traces as soon as the Fragment is
// attached to its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.recordScreenTrace();
}
}
@Override
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {
super.onFragmentDetached(fm, f);
// TODO (4): Stop recording the screen traces as soon as the Fragment is
// detached from its host Activity.
if (FRAGMENT_TAG.equals(f.getTag()) && screenTrace.isScreenTraceSupported()) {
screenTrace.sendScreenTrace();
}
// Unregister Fragment lifecycle callbacks after the Fragment is detached
fm.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks);
}
};
- Réexécutez l'application, puis appuyez sur le bouton
LOAD FRAGMENT
. Patientez quelques secondes, puis cliquez surback button
dans la barre de navigation inférieure.
Filtrez le logcat avec Logging trace metric (Métrique de trace de journalisation), puis recherchez des journaux comme ceux ci-dessous :
I/FirebasePerformance: Logging trace metric: _st_MainActivity-TestFragment (duration: XXXms)
Filtrez Logcat avec "FireperfViews", puis recherchez des journaux semblables à ceux ci-dessous :
D/FireperfViews: sendScreenTrace MainActivity-TestFragment, name: _st_MainActivity-TestFragment, total_frames: XX, slow_frames: XX, frozen_frames: XX
🎉 Félicitations ! Vous avez réussi à mesurer les frames lents/figés pour un fragment et à signaler ces données à Firebase Performance Monitoring. Nous examinerons les métriques enregistrées dans la console Firebase plus loin dans cet atelier de programmation.
9. Consulter les métriques dans la console Firebase
- Dans le logcat, cliquez sur l'URL de la console Firebase pour accéder à la page d'informations d'une trace.
Vous pouvez également sélectionner le projet contenant votre application dans la console Firebase. Dans le panneau de gauche, recherchez la section Release & Monitor (Lancement et surveillance), puis cliquez sur Performance (Performances).
- Dans l'onglet principal Tableau de bord, faites défiler la page jusqu'au tableau des traces, puis cliquez sur l'onglet Traces personnalisées. Dans ce tableau, vous verrez les traces de code personnalisé que nous avons ajoutées précédemment, ainsi que des traces prêtes à l'emploi, comme la trace
_app_start
. - Recherchez vos deux traces de code personnalisé,
TestActivity-LoadTime
etTestFragment-LoadTime
. Cliquez sur la durée de l'un ou l'autre pour afficher plus de détails sur les données collectées.
- La page d'informations sur la trace de code personnalisé affiche des informations sur la durée de la trace (c'est-à-dire le temps de chargement mesuré).
- Vous pouvez également afficher les données sur les performances de votre trace d'écran personnalisée.
- Revenez à l'onglet principal Tableau de bord, faites défiler la page jusqu'au tableau des traces, puis cliquez sur l'onglet Rendu de l'écran. Dans ce tableau, vous verrez les traces d'écran personnalisées que nous avons ajoutées précédemment, ainsi que les traces d'écran prêtes à l'emploi, comme la trace
MainActivity
. - Recherchez votre trace d'écran personnalisée,
MainActivity-TestFragment
. Cliquez sur le nom de la trace pour afficher les données agrégées des frames lents et figés.
10. Félicitations
Félicitations ! Vous avez réussi à mesurer le temps de chargement et les performances de rendu d'écran d'une activité et d'un fragment à l'aide de Firebase Performance Monitoring.
Ce que vous avez accompli
- Vous avez intégré Firebase Performance Monitoring à une application exemple.
- Vous comprenez maintenant le cycle de vie du chargement des vues.
- Vous avez mesuré le temps de chargement d'une activité et d'un fragment en ajoutant des traces de code personnalisées.
- Vous avez enregistré des frames lents/figés en ajoutant des traces d'écran personnalisées avec des métriques personnalisées.
Étape suivante
Firebase Performance offre plus de façons de mesurer les performances de votre application que le traçage personnalisé. Il mesure automatiquement les données de performances concernant le temps de démarrage de l'application, l'application au premier plan et l'application en arrière-plan. Il est temps de vérifier ces métriques dans la console Firebase.
Firebase Performance propose également la surveillance automatique des requêtes réseau HTTP/S. Vous pouvez ainsi instrumenter facilement les requêtes réseau sans écrire une seule ligne de code. Pouvez-vous essayer d'envoyer des requêtes réseau depuis votre application et de trouver les métriques dans la console Firebase ?
Bonus
Maintenant que vous savez comment mesurer le temps de chargement et les performances de rendu d'écran de votre activité/fragment à l'aide de traces de code personnalisées, pouvez-vous explorer notre base de code Open Source pour voir si vous pouvez capturer ces métriques prêtes à l'emploi pour toute activité/tout fragment faisant partie de l'application ? N'hésitez pas à envoyer la demande de pull si vous le souhaitez :-)
11. Apprentissage bonus
Comprendre ce qui se passe lors du chargement d'une activité vous aidera à mieux comprendre les caractéristiques de performances de votre application. Dans une étape précédente, nous avons décrit de manière générale ce qui se passe lors du chargement d'une activité, mais le diagramme suivant décrit chaque phase beaucoup plus en détail.