Creare profili di riferimento

Genera automaticamente profili per ogni release dell'app utilizzando la libreria Jetpack Macrobenchmark e BaselineProfileRule. Ti consigliamo di utilizzare com.android.tools.build:gradle:8.0.0 o una versione successiva, che include miglioramenti della build durante l'utilizzo dei profili di riferimento.

Di seguito sono riportati i passaggi generali per creare un nuovo profilo di riferimento:

  1. Configura il modulo Profilo di riferimento.
  2. Definisci il test JUnit che consente di generare profili di riferimento.
  3. Aggiungi i percorsi dell'utente critici (CUJ) che vuoi ottimizzare.
  4. Genera il profilo di riferimento.

Dopo aver generato il profilo di riferimento, confrontalo utilizzando un dispositivo fisico per misurare i miglioramenti della velocità.

Crea un nuovo profilo di riferimento con AGP 8.2 o versioni successive

Il modo più semplice per creare un nuovo profilo di riferimento è utilizzare il modello del modulo del profilo di riferimento, disponibile a partire da Android Studio Iguana e dal plug-in Android Gradle (AGP) 8.2.

Il modello del modulo Generatore di profili di riferimento di Android Studio automatizza la creazione di un nuovo modulo per generare e benchmark i profili di riferimento. L'esecuzione del modello genera la maggior parte della configurazione di build tipica, della generazione del profilo di riferimento e del codice di verifica. Il modello crea codice per generare e confrontare i profili di riferimento per misurare l'avvio dell'app.

Configurare il modulo Profilo di riferimento

Per eseguire il modello del modulo Profilo di riferimento, segui questi passaggi:

  1. Seleziona File > Nuovo > Nuovo modulo
  2. Seleziona il modello Generatore di profilo di riferimento nel riquadro Modelli e configuralo:
    Figura 1. Modello di modulo Generatore di profili di riferimento.

    I campi del modello sono i seguenti:

    • Applicazione di destinazione: definisce per quale app viene generato il profilo di riferimento. Se nel progetto è presente un solo modulo dell'app, l'elenco contiene un solo elemento.
    • Nome modulo: il nome che vuoi per il modulo Profilo di riferimento che stai creando.
    • Nome pacchetto: il nome del pacchetto che vuoi utilizzare per il modulo Profilo di riferimento.
    • Lingua: se vuoi che il codice generato sia Kotlin o Java.
    • Linguaggio di configurazione della build: se vuoi utilizzare Kotlin Script (KTS) o Groovy per gli script di configurazione della build.
    • Utilizzo di un dispositivo gestito da Gradle: se stai utilizzando dispositivi gestiti da Gradle per testare la tua app.
  3. Fai clic su Fine per creare il nuovo modulo. Se utilizzi il controllo del codice sorgente, ti potrebbe essere chiesto di aggiungere al controllo del codice sorgente i file dei moduli appena creati.

Definisci il generatore del profilo di riferimento

Il modulo appena creato contiene test per generare e confrontare il profilo di riferimento, nonché per testare solo l'avvio dell'app di base. Ti consigliamo di aumentarli in modo da includere CUJ e flussi di lavoro di avvio avanzati. Assicurati che tutti i test relativi all'avvio dell'app siano in un blocco rule con includeInStartupProfile impostato su true; al contrario, per prestazioni ottimali, assicurati che eventuali test non correlati all'avvio dell'app non siano inclusi in un profilo di avvio. Le ottimizzazioni dell'avvio dell'app vengono utilizzate per definire una parte speciale di un profilo di riferimento chiamato profilo di avvio.

È utile per la manutenibilità se astrai questi CUJ al di fuori del profilo di riferimento e del codice di benchmark generati, in modo che possano essere utilizzati per entrambi. Ciò significa che le modifiche ai CUJ vengono utilizzate in modo coerente.

Genera e installa il profilo di riferimento

Il modello del modulo del profilo di riferimento aggiunge una nuova configurazione di esecuzione per generare il profilo di riferimento. Se utilizzi le versioni di prodotto, Android Studio crea più configurazioni di esecuzione in modo da poter generare profili di riferimento separati per ogni versione.

La configurazione di esecuzione Genera profilo di riferimento.
Figura 2. L'esecuzione di questa configurazione genera il profilo di riferimento.

Al completamento della configurazione dell'esecuzione di Genera profilo di riferimento, il profilo di riferimento generato viene copiato nel file src/variant/generated/baselineProfiles/baseline-prof.txt del modulo che viene profilato. Le opzioni delle varianti sono il tipo di build di release o una variante di build che coinvolge il tipo di build di release.

Il profilo di riferimento generato è stato creato originariamente in build/outputs. Il percorso completo è dettato dalla variante o dalla versione dell'app profilata e dal fatto che utilizzi un dispositivo gestito da Gradle o un dispositivo connesso per la profilazione. Se utilizzi i nomi utilizzati dal codice e dalle configurazioni di build generate dal modello, il profilo di riferimento viene creato nel file build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. Probabilmente non dovrai interagire direttamente con questa versione del profilo di riferimento generato, a meno che tu non la copi manualmente nei moduli di destinazione (opzione sconsigliata).

Creare un nuovo profilo di riferimento con AGP 8.1

Se non riesci a utilizzare il modello di modulo Baseline Profile, usa il modello di modulo Macrobenchmark e il plug-in Gradle del profilo Baseline per creare un nuovo profilo di riferimento. Ti consigliamo di usare questi strumenti a partire da Android Studio Giraffe e AGP 8.1.

Ecco i passaggi per creare un nuovo profilo Baseline utilizzando il modello di modulo Macrobenchmark e il plug-in Gradle Baseline Profile:

  1. Configura un modulo Macrobenchmark nel tuo progetto Gradle.
  2. Definisci un nuovo corso denominato BaselineProfileGenerator:
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }
    

    Il generatore può contenere interazioni con la tua app oltre all'avvio dell'app. Ciò consente di ottimizzare le prestazioni di runtime della tua app, ad esempio elenchi a scorrimento, esecuzione di animazioni e navigazione all'interno di Activity. Visualizza altri esempi di test che utilizzano @BaselineProfileRule per migliorare i percorsi critici degli utenti.

  3. Aggiungi il plug-in per Gradle Baseline Profile (libs.plugins.androidx.baselineprofile). Il plug-in semplifica la generazione dei profili di riferimento e la loro gestione in futuro.

  4. Per generare il profilo di riferimento, esegui le attività Gradle :app:generateBaselineProfile o :app:generateVariantBaselineProfile nel terminale.

    Esegui il generatore come test strumentato su un dispositivo fisico rooted, un emulatore o un dispositivo gestito Gradle. Se utilizzi un dispositivo gestito da Gradle, imposta aosp come systemImageSource, perché è necessario l'accesso root per il generatore di profili Baseline.

    Al termine dell'attività di generazione, il profilo di riferimento viene copiato in app/src/variant/generated/baselineProfiles.

Crea un nuovo profilo di riferimento senza modelli

Ti consigliamo di creare un profilo Baseline utilizzando il modello di modulo Baseline Profile di Android Studio (opzione preferita) o il modello di Macrobenchmark, ma puoi anche utilizzare il plug-in Gradle Baseline Profile da solo. Per ulteriori informazioni sul plug-in Gradle del profilo Baseline, consulta Configurare la generazione del profilo Baseline.

Ecco come creare un profilo di riferimento utilizzando direttamente il plug-in Gradle del profilo Baseline:

  1. Crea un nuovo modulo com.android.test, ad esempio :baseline-profile.
  2. Configura il file build.gradle.kts per :baseline-profile:

    1. Applica il plug-in androidx.baselineprofile.
    2. Assicurati che targetProjectPath indirizzi al modulo :app.
    3. Se vuoi, aggiungi un dispositivo gestito da Gradle (GMD). Nell'esempio seguente è pixel6Api31. Se non specificato, il plug-in utilizza un dispositivo connesso, emulato o fisico.
    4. Applica la configurazione che preferisci, come mostrato nell'esempio seguente.

    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
    }
    

    trendy

    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. Crea un test del profilo di riferimento nel modulo di test :baseline-profile. L'esempio seguente è un test che avvia l'app e attende in caso di inattività.

    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. Aggiorna il file build.gradle.kts nel modulo dell'app, ad esempio :app.

    1. Applica il plug-in androidx.baselineprofile.
    2. Aggiungi una dipendenza baselineProfile al modulo :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"))
    }
    

    trendy

    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. Genera il profilo eseguendo le attività Gradle :app:generateBaselineProfile o :app:generateVariantBaselineProfile.

  6. Al termine dell'attività di generazione, il profilo di riferimento viene copiato in app/src/variant/generated/baselineProfiles.

Crea un nuovo Profilo di riferimento con AGP 7.3-7.4

È possibile generare profili di riferimento con AGP 7.3-7.4, ma consigliamo vivamente di eseguire l'upgrade ad almeno AGP 8.1 in modo da poter utilizzare il plug-in Gradle Baseline Profile e le sue funzionalità più recenti.

Se devi creare profili di riferimento con AGP 7.3-7.4, i passaggi sono gli stessi dei passaggi per AGP 8.1, con le seguenti eccezioni:

Applica manualmente le regole generate

Il generatore di profili di riferimento crea un file di testo HRF (Human Readable Format) sul dispositivo e lo copia sulla macchina host. Per applicare il profilo generato al codice, segui questi passaggi:

  1. Individua il file HRF nella cartella di build del modulo in cui generi il profilo: [module]/build/outputs/managed_device_android_test_additional_output/[device].

    I profili seguono lo schema di denominazione [class name]-[test method name]-baseline-prof.txt, che ha il seguente aspetto: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. Copia il profilo generato in src/main/ e rinomina il file in baseline-prof.txt.

  3. Aggiungi una dipendenza alla libreria ProfileInstallaer nel file build.gradle.kts della tua app per abilitare la compilazione del profilo di riferimento locale in cui i profili Cloud non sono disponibili. Questo è l'unico modo per trasferire localmente un profilo di riferimento.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.3.1")
    }
    
  4. Crea la versione di produzione della tua app mentre le regole HRF applicate sono compilate in formato binario e incluse nell'APK o nell'AAB. Poi distribuisci la tua app come di consueto.

Eseguire un benchmark del profilo di riferimento

Per eseguire il benchmark del tuo profilo di riferimento, crea una nuova configurazione di esecuzione di test strumentata su Android dall'azione gutter che esegue i benchmark definiti nel file StartupBenchmarks.kt o StartupBencharks.java. Per scoprire di più sui test dei benchmark, consulta Creare una classe Macrobenchmark e Automatizzare la misurazione con la libreria Macrobenchmark.

Figura 3. Esegui i test Android dall'azione di gronda.

Se esegui questa operazione in Android Studio, l'output della build contiene i dettagli dei miglioramenti della velocità forniti dal profilo di riferimento:

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

Acquisisci tutti i percorsi di codice richiesti

Le due metriche principali per la misurazione dei tempi di avvio dell'app sono le seguenti:

Tempo per la visualizzazione iniziale (TTID)
Il tempo necessario per visualizzare il primo frame dell'interfaccia utente dell'applicazione.
Tempo per la visualizzazione completa (TTFD)
TTID più il tempo per visualizzare i contenuti caricati in modo asincrono dopo la visualizzazione del frame iniziale.

La TTFD viene riportata dopo aver chiamato il metodo reportFullyDrawn() di ComponentActivity. Se reportFullyDrawn() non viene mai chiamato, viene segnalato il TTID. Potrebbe essere necessario ritardare la chiamata di reportFullyDrawn() fino al completamento del caricamento asincrono. Ad esempio, se la UI contiene un elenco dinamico come RecyclerView o un elenco lento, l'elenco potrebbe essere completato da un'attività in background che viene completata dopo che l'elenco è stato disegnato per la prima volta e, di conseguenza, dopo che l'interfaccia utente è stata contrassegnata come completamente tracciata. In questi casi, il codice eseguito dopo che l'UI raggiunge lo stato disegnato completamente non è incluso nel profilo di riferimento.

Per includere la compilazione dell'elenco nel profilo di riferimento, ottieni FullyDrawnReporter utilizzando getFullyDrawnReporter() e aggiungi un reporter nel codice dell'app. Rilascia l'autore della segnalazione quando l'attività in background ha completato il completamento dell'elenco. FullyDrawnReporter non richiama il metodo reportFullyDrawn() finché non vengono rilasciati tutti gli autori di segnalazioni. In questo modo, il profilo di riferimento include i percorsi di codice necessari per compilare l'elenco. Questo non modifica il comportamento dell'app per l'utente, ma consente al profilo di riferimento di includere tutti i percorsi di codice necessari.

Se l'app utilizza Jetpack Compose, utilizza le API seguenti per indicare lo stato disegnato completamente:

  • ReportDrawn indica che il componibile è immediatamente pronto per l'interazione.
  • ReportDrawnWhen utilizza un predicato, ad esempio list.count > 0, per indicare quando il componibile è pronto per l'interazione.
  • ReportDrawnAfter applica un metodo di sospensione che, una volta completato, indica che il tuo componibile è pronto per l'interazione.