Créer des profils de référence

Générez automatiquement des profils pour chaque version d'application à l'aide de la bibliothèque Jetpack Macrobenchmark et de BaselineProfileRule. Nous vous recommandons d'utiliser com.android.tools.build:gradle:8.0.0 ou une version ultérieure, qui offre des améliorations de compilation lorsque vous utilisez des profils de référence.

Voici la procédure à suivre pour créer un profil de référence :

  1. Configurez le module de profil de référence.
  2. Définissez le test JUnit qui permet de générer des profils de référence.
  3. Ajoutez les critical user journeys (CUJ) que vous souhaitez optimiser.
  4. Générez le profil de référence.

Après avoir généré le profil de référence, comparez-le à l'aide d'un appareil physique pour mesurer les améliorations de la vitesse.

Créer un profil de référence avec AGP 8.2 ou version ultérieure

Le moyen le plus simple de créer un profil de référence consiste à utiliser le modèle du module de profil de référence, disponible à partir d'Android Studio Iguana et du plug-in Android Gradle (AGP) 8.2.

Le modèle du module du générateur de profils de référence Android Studio automatise la création d'un module en vue de générer et de comparer des profils de référence. L'exécution du modèle génère la plupart des configurations de compilation, de la génération de profils de référence et du code de validation. Le modèle crée le code permettant de générer et de comparer des profils de référence afin de mesurer le démarrage de l'application.

Configurer le module de profil de référence

Pour exécuter le modèle du module de profil de référence, procédez comme suit :

  1. Sélectionnez File > New > New Module (Fichier > Nouveau > Nouveau module).
  2. Sélectionnez le modèle Baseline Profile Generator (Générateur de profils de référence) dans le panneau Templates (Modèles), puis configurez-le :
    Figure 1 : Modèle du module du générateur de profils de référence

    Les champs du modèle sont les suivants :

    • Target application (Application cible) : définit l'application pour laquelle le profil de référence est généré. Si votre projet ne comporte qu'un seul module d'application, cette liste ne contient qu'un seul élément.
    • Module name (Nom du module) : nom que vous souhaitez donner au module de profil de référence en cours de création.
    • Package name (Nom du package) : nom du package que vous souhaitez pour le module de profil de référence.
    • Langage (Langage) : indiquez si vous souhaitez que le code généré soit en Kotlin ou en Java.
    • Build configuration language (Langage de configuration de compilation) : indiquez si vous souhaitez utiliser le script Kotlin (KTS) ou Groovy pour vos scripts de configuration de compilation.
    • Utiliser un appareil géré par Gradle: indique si vous utilisez des appareils gérés par Gradle pour tester votre application.
  3. Cliquez sur Finish (Terminer) pour créer le module. Si vous utilisez le contrôle des sources, vous pouvez être invité à y ajouter les fichiers du module que vous venez de créer.

Définir le générateur de profils de référence

Le nouveau module contient des tests permettant de générer et de comparer le profil de référence, et teste uniquement le démarrage de base de l'application. Nous vous recommandons d'y ajouter les CUJ et les workflows de démarrage avancés. Assurez-vous que tous les tests liés au démarrage de l'application se trouvent dans un bloc rule avec includeInStartupProfile défini sur true. À l'inverse, pour des performances optimales, assurez-vous que les tests non liés au démarrage de l'application ne sont pas inclus dans un profil de démarrage. Les optimisations du démarrage de l'application permettent de définir une partie spéciale d'un profil de référence appelée profil de démarrage.

La gestion sera plus simple si vous extrayez ces CUJ du profil de référence et du code d'analyse générés afin qu'ils puissent être utilisés dans ces deux contextes. Les modifications apportées à vos CUJ seront ainsi utilisées de manière cohérente.

Générer et installer le profil de référence

Le modèle du module de profil de référence ajoute une nouvelle configuration d'exécution pour générer le profil de référence : Si vous utilisez différents types de produit, Android Studio crée plusieurs configurations d'exécution afin que vous puissiez générer des profils de référence distincts pour chacun d'eux.

Configuration d'exécution de la génération du profil de référence.
Figure 2 : L'exécution de cette configuration génère le profil de référence.

Une fois la configuration d'exécution Generate Baseline Profile (Générer un profil de référence) terminée, le profil de référence généré est copié dans le fichier src/variant/generated/baselineProfiles/baseline-prof.txt du module en cours de profilage. Les options de variante sont les suivantes : le type de compilation ou une variante de compilation impliquant le type de compilation.

Le profil de référence généré est créé dans build/outputs. Le chemin d'accès complet dépend de la variante ou du type de l'application en cours de profilage. Il varie aussi selon que vous utilisez un appareil géré par Gradle ou un appareil connecté pour le profilage. Si vous utilisez les noms utilisés par le code et les configurations de compilation générés par le modèle, le profil de référence est créé dans le fichier build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. Vous n'aurez probablement pas à interagir directement avec cette version du profil de référence généré, sauf si vous la copiez manuellement dans les modules cibles (non recommandé).

Créer un profil de référence avec AGP 8.1

Si vous ne pouvez pas utiliser le modèle du module de profil de référence, utilisez le modèle du module Macrobenchmark et le plug-in Baseline Profile Gradle pour créer un profil de référence. Nous vous recommandons d'utiliser ces outils à partir d'Android Studio Giraffe et d'AGP 8.1.

Voici les étapes à suivre pour créer un profil de référence à l'aide du modèle du module Macrobenchmark et du plug-in Baseline Profile Gradle :

  1. Configurez un module Macrobenchmark dans votre projet Gradle.
  2. Définissez une nouvelle classe appelée BaselineProfileGenerator :
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }

    Le générateur peut contenir des interactions avec votre appli au-delà de son démarrage. Cela vous permet d'optimiser les performances d'exécution de votre application, comme le défilement de listes, l'exécution d'animations et la navigation dans une Activity. Consultez d'autres exemples de tests qui utilisent @BaselineProfileRule pour améliorer les critical user journeys.

  3. Ajoutez le plug-in Baseline Profile Gradle (libs.plugins.androidx.baselineprofile). Ce plug-in facilite la génération de profils de référence et leur gestion à l'avenir.

  4. Pour générer le profil de référence, exécutez les tâches Gradle :app:generateBaselineProfile ou :app:generateVariantBaselineProfile dans le terminal.

    Exécutez le générateur en tant que test instrumenté sur un appareil physique en mode root, un émulateur ou un appareil géré par Gradle. Si vous utilisez un appareil géré par Gradle, définissez aosp comme systemImageSource, car vous aurez besoin d'un accès racine au générateur de profils de référence.

    À la fin de la tâche de génération, le profil de référence est copié dans app/src/variant/generated/baselineProfiles.

Créer un profil de référence sans modèle

Nous vous recommandons de créer un profil de référence à l'aide du modèle du module de profil de référence d'Android Studio (recommandé) ou du modèle Macrobenchmark, mais vous pouvez également utiliser le plug-in Baseline Profile Gradle seul. Pour en savoir plus sur le plug-in Baseline Profile Gradle, consultez la section Configurer la génération de profils de référence.

Voici comment créer directement un profil de référence à l'aide du plug-in Baseline Profile Gradle :

  1. Créez un module com.android.test, par exemple :baseline-profile.
  2. Configurez le fichier build.gradle.kts pour :baseline-profile :

    1. Appliquez le plug-in androidx.baselineprofile.
    2. Assurez-vous que targetProjectPath pointe vers le module :app.
    3. Vous pouvez également ajouter un appareil géré par Gradle. Dans l'exemple suivant, il s'agit de pixel6Api31. S'il n'est pas spécifié, le plug-in utilise un appareil connecté soit émulé, soit physique.
    4. Appliquez la configuration de votre choix, comme indiqué dans l'exemple suivant.

    Kotlin

    plugins {
        id("com.android.test")
        id("androidx.baselineprofile")
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath = ":app"
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device = "Pixel 6"
                apiLevel = 31
                systemImageSource = "aosp"
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices += "pixel6Api31"
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices = false
    }

    Groovy

    plugins {
        id 'com.android.test'
        id 'androidx.baselineprofile'
    }
    
    android {
        defaultConfig {
            ...
        }
    
        // Point to the app module, the module that you're generating the Baseline Profile for.
        targetProjectPath ':app'
        // Configure a GMD (optional).
        testOptions.managedDevices.devices {
            pixel6Api31(com.android.build.api.dsl.ManagedVirtualDevice) {
                device 'Pixel 6'
                apiLevel 31
                systemImageSource 'aosp'
            }
        }
    }
    
    dependencies { ... }
    
    // Baseline Profile Gradle plugin configuration. Everything is optional. This
    // example uses the GMD added earlier and disables connected devices.
    baselineProfile {
        // Specifies the GMDs to run the tests on. The default is none.
        managedDevices ['pixel6Api31']
        // Enables using connected devices to generate profiles. The default is
        // `true`. When using connected devices, they must be rooted or API 33 and
        // higher.
        useConnectedDevices false
    }
  3. Créez un test de profil de référence dans le module de test :baseline-profile. L'exemple suivant est un test qui lance l'application et attend l'inactivité.

    Kotlin

    class BaselineProfileGenerator {
    
        @get:Rule
        val baselineRule = BaselineProfileRule()
    
        @Test
        fun startupBaselineProfile() {
            baselineRule.collect("com.myapp") {
                startActivityAndWait()
            }
        }
    }

    Java

    public class BaselineProfileGenerator {
    
        @Rule
        Public BaselineProfileRule baselineRule = new BaselineProfileRule();
    
        @Test
        Public void startupBaselineProfile() {
            baselineRule.collect(
                "com.myapp",
                (scope -> {
                    scope.startActivityAndWait();
                    Return Unit.INSTANCE;
                })
            )
        }
    }
  4. Mettez à jour le fichier build.gradle.kts dans le module de l'application, par exemple :app.

    1. Appliquez le plug-in androidx.baselineprofile.
    2. Ajoutez une dépendance baselineProfile au module :baseline-profile.

    Kotlin

    plugins {
        id("com.android.application")
        id("androidx.baselineprofile")
    }
    
    android {
        // There are no changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile(project(":baseline-profile"))
    }

    Groovy

    plugins {
        id 'com.android.application'
        id 'androidx.baselineprofile'
    }
    
    android {
        // No changes to the `android` block.
        ...
    }
    
    dependencies {
        ...
        // Add a `baselineProfile` dependency on the `:baseline-profile` module.
        baselineProfile ':baseline-profile'
    }
  5. Générez le profil en exécutant les tâches Gradle :app:generateBaselineProfile ou :app:generateVariantBaselineProfile.

  6. À la fin de la tâche de génération, le profil de référence est copié dans app/src/variant/generated/baselineProfiles.

Créer un profil de référence avec AGP 7.3 à 7.4

Il est possible de générer des profils de référence avec AGP 7.3 à 7.4, mais nous vous recommandons vivement de passer à AGP 8.1 ou version ultérieure afin de pouvoir utiliser le plug-in Baseline Profile Gradle et ses dernières fonctionnalités.

Si vous devez créer des profils de référence avec AGP 7.3 à 7.4, la procédure est identique à celle pour AGP 8.1, à quelques exceptions près :

Appliquer manuellement les règles générées

Le générateur de profils de référence crée un fichier texte HRF (Human Readable Format) sur l'appareil et le copie sur votre machine hôte. Pour appliquer le profil généré à votre code, procédez comme suit :

  1. Recherchez le fichier HRF dans le dossier de compilation du module dans lequel vous générez le profil : [module]/build/outputs/managed_device_android_test_additional_output/[device].

    Les profils suivent le format de nommage [class name]-[test method name]-baseline-prof.txt, qui se présente comme suit : BaselineProfileGenerator-startup-baseline-prof.txt

  2. Copiez le profil généré dans src/main/ et renommez le fichier baseline-prof.txt.

  3. Ajoutez une dépendance à la bibliothèque ProfileInstaller dans le fichier build.gradle.kts de votre application pour activer la compilation locale du profil de référence où les profils cloud ne sont pas disponibles. Il s'agit du seul moyen de télécharger indépendamment un profil de référence en local.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. Créez la version de production de votre application, tandis que les règles HRF appliquées sont compilées au format binaire et incluses dans l'APK ou l'AAB. Distribuez ensuite votre application comme vous le faites habituellement.

Effectuer une analyse comparative du profil de référence

Pour comparer votre profil de référence, créez une configuration d'exécution de test d'instrumentation Android à partir de l'action "marge" qui exécute les analyses comparatives définies dans le fichier StartupBenchmarks.kt ou StartupBencharks.java. Pour en savoir plus sur les tests d'analyse comparative, consultez Créer une classe Macrobenchmark et Automatiser les mesures avec la bibliothèque Macrobenchmark.

Figure 3 : Exécuter des tests Android à partir de la marge

Lorsque vous exécutez cette commande dans Android Studio, le résultat de la compilation contient des informations sur les améliorations de vitesse fournies par le profil de référence :

StartupBenchmarks_startupCompilationBaselineProfiles
timeToInitialDisplayMs   min 161.8,   median 178.9,   max 194.6
StartupBenchmarks_startupCompilationNone
timeToInitialDisplayMs   min 184.7,   median 196.9,   max 202.9

Capturer tous les chemins de code requis

Les deux métriques clés pour mesurer les temps de démarrage de l'application sont les suivantes :

Le délai d'affichage initial (TTID)
Temps nécessaire pour afficher le premier frame de l'interface utilisateur de l'application.
Le délai d'affichage total (TTFD)
Le délai d'affichage initial plus la durée d'affichage du contenu chargé de manière asynchrone après l'affichage du frame initial.

Le TTFD est indiqué une fois que la méthode reportFullyDrawn() de ComponentActivity est appelée. Si reportFullyDrawn() n'est jamais appelé, le TTID est indiqué à la place. Vous devrez peut-être différer l'appel de reportFullyDrawn() jusqu'à la fin du chargement asynchrone. Par exemple, si l'interface utilisateur contient une liste dynamique telle qu'une RecyclerView ou une liste différée, elle peut être renseignée par une tâche en arrière-plan qui se terminera après le premier affichage de la liste et, par conséquent, une fois que l'interface utilisateur sera marquée comme entièrement dessinée. Dans ce cas, le code qui s'exécute une fois que l'interface utilisateur est complètement dessiné n'est pas inclus dans le profil de référence.

Pour inclure la liste de membres dans votre profil de référence, obtenez FullyDrawnReporter à l'aide de getFullyDrawnReporter() et ajoutez-y un "rapporteur" dans le code de votre application. Vous devrez libérer ce rapporteur une fois que la tâche en arrière-plan aura rempli la liste. FullyDrawnReporter n'appelle pas la méthode reportFullyDrawn() tant que tous les rapporteurs ajoutés ne sont pas libérés. De cette façon, le profil de référence inclut les chemins de code requis pour remplir la liste. Cela ne modifie pas le comportement de l'application aux yeux de l'utilisateur, mais permet au profil de référence d'inclure tous les chemins de code nécessaires.

Si votre application utilise Jetpack Compose, vous pouvez utiliser les API suivantes pour indiquer l'état entièrement dessiné :

  • ReportDrawn indique que votre composable est immédiatement prêt à interagir.
  • ReportDrawnWhen utilise un prédicat, comme list.count > 0, pour indiquer à quel moment votre composable sera prêt à interagir.
  • ReportDrawnAfter utilise une méthode de suspension qui, lorsqu'elle se termine, indique que votre composable est prêt à interagir.