Creare profili di riferimento

I profili Baseline sono essenziali per massimizzare le prestazioni di Jetpack Compose. La precompilazione dei Critical User Journey contribuisce a garantire che la UI di Compose venga visualizzata senza problemi.

Genera automaticamente i 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 versioni successive per sfruttare i miglioramenti della build quando utilizzi i profili di riferimento.

Ecco i passaggi generali per creare un nuovo profilo di riferimento:

  1. Configura il modulo Baseline Profile.
  2. Definisci il test JUnit che aiuta a generare i profili di riferimento.
  3. Aggiungi i Critical User Journey (CUJ) che vuoi ottimizzare.
  4. Genera il profilo di riferimento.

Dopo aver generato il profilo Baseline, esegui il benchmark 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 di modulo Baseline Profile Generator di Android Studio automatizza la creazione di un nuovo modulo per generare ed eseguire il benchmark dei profili di riferimento. L'esecuzione del modello genera la maggior parte del codice di configurazione di compilazione, generazione del profilo di riferimento e verifica tipico. Il modello crea il codice per generare ed eseguire il benchmark dei profili di riferimento per misurare l'avvio dell'app.

Configura il modulo del profilo di riferimento

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

  1. Seleziona File > Nuovo > Nuovo modulo.
  2. Seleziona il modello Baseline Profile Generator nel riquadro Templates e configuralo:
    Figura 1. Baseline Profile Generator.
    I campi del modello sono i seguenti:
    • Applicazione di destinazione: l'app per cui viene generato il profilo di riferimento. Se nel progetto è presente un solo modulo dell'app, in questo elenco è presente un solo elemento.
    • Nome del modulo: il nome che vuoi assegnare al modulo del profilo Baseline in fase di creazione.
    • Nome del pacchetto: il nome del pacchetto che vuoi per il modulo del profilo di riferimento.
    • Language (Lingua): se vuoi che il codice generato sia Kotlin o Java.
    • Linguaggio di configurazione di compilazione: se vuoi utilizzare Kotlin Script (KTS) o Groovy per gli script di configurazione di compilazione.
    • Utilizza un dispositivo gestito da Gradle: indica se utilizzi 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 i file del modulo appena creati al controllo del codice sorgente.

Definisci il generatore di profili di riferimento

Il modulo appena creato contiene test per generare ed eseguire il benchmark del profilo di riferimento e testare solo l'avvio di base dell'app. Ti consigliamo di ampliarli per includere i CUJ e i workflow 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 un rendimento ottimale, assicurati che tutti i test non relativi 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 baseline, chiamata profilo di avvio.

Per facilitare la manutenzione, è utile astrarre questi CUJ al di fuori del codice del profilo di riferimento e del benchmark generato, 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 baseline

Il modello di modulo del profilo di riferimento aggiunge una nuova configurazione di esecuzione per generare il profilo di riferimento. Se utilizzi le versioni prodotto, Android Studio crea più configurazioni di esecuzione in modo da poter generare profili Baseline 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 termine della configurazione di esecuzione Genera profilo di riferimento, il profilo di riferimento generato viene copiato nel file src/variant/generated/baselineProfiles/baseline-prof.txt nel modulo di cui viene eseguita la profilazione. Le opzioni della variante 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 viene creato originariamente in build/outputs. Il percorso completo è determinato dalla variante o dalla versione dell'app di cui viene eseguita la profilazione e dall'utilizzo di un dispositivo gestito da Gradle o di un dispositivo connesso per la profilazione. Se utilizzi i nomi utilizzati dalle configurazioni di codice e 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 lo stia copiando manualmente nei moduli di destinazione (operazione sconsigliata).

Crea un nuovo profilo Baseline con AGP 8.1

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

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

  1. Configura un modulo Macrobenchmark nel tuo progetto Gradle.
  2. Definisci una nuova classe denominata 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. In questo modo puoi ottimizzare le prestazioni di runtime della tua app, ad esempio lo scorrimento degli elenchi, l'esecuzione di animazioni e la navigazione all'interno di un Activity. Guarda altri esempi di test che utilizzano @BaselineProfileRule per migliorare i Critical User Journey.

  3. Aggiungi il plug-in Gradle del profilo di riferimento (libs.plugins.androidx.baselineprofile). Il plug-in semplifica la generazione dei profili di riferimento e la loro manutenzione 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 di instrumentazione su un dispositivo fisico con root, un emulatore o un dispositivo gestito da Gradle. Se utilizzi un dispositivo gestito da Gradle, imposta aosp come systemImageSource, perché hai bisogno dell'accesso root per il generatore di profili Baseline.

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

Crea un nuovo profilo di riferimento senza modelli

Ti consigliamo di creare un profilo di riferimento utilizzando il modello di modulo del profilo di riferimento di Android Studio (opzione preferita) o il modello Macrobenchmark, ma puoi anche utilizzare il plug-in Gradle del profilo di riferimento da solo. Per scoprire di più sul plug-in Gradle per i profili Baseline, consulta Configura la generazione dei profili Baseline.

Ecco come creare un profilo di baseline utilizzando direttamente il plug-in Gradle per i profili di 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 punti al modulo :app.
    3. Facoltativamente, aggiungi un dispositivo gestito da Gradle (GMD). Nel seguente esempio, è 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
    }

    Alla moda

    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 genera un profilo di riferimento per l'avvio dell'app.

        class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                uiAutomator { startApp(PACKAGE_NAME) }
            }
        )
    }
    
  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"))
    }

    Alla moda

    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.

Esegui il benchmark del profilo di baseline

Per eseguire il benchmark del profilo di riferimento, crea una nuova configurazione di esecuzione dei test strumentati Android dall'azione del margine che esegue i benchmark definiti nel file StartupBenchmarks.kt. Per scoprire di più sui test di benchmark, consulta Crea una classe Macrobenchmark e Esegui il benchmark dei profili di riferimento con la libreria Macrobenchmark.

Figura 3. Esegui i test Android dall'azione del margine.

Quando 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 del codice richiesti

Le due metriche chiave per misurare i tempi di avvio delle app sono le seguenti:

Il TTFD viene registrato una volta chiamato il metodo reportFullyDrawn di ComponentActivity. Se reportFullyDrawn non viene mai chiamato, viene segnalato il TTID. Potresti dover ritardare la chiamata di reportFullyDrawn fino al completamento del caricamento asincrono. Ad esempio, se la UI contiene un elenco lazy dinamico, l'elenco potrebbe essere compilato da un'attività in background che viene completata dopo il primo disegno dell'elenco e, di conseguenza, dopo che la UI è stata contrassegnata come completamente disegnata. In questi casi, il codice eseguito dopo che la UI raggiunge lo stato di disegno completo non viene incluso nel profilo di riferimento.

Per includere la compilazione dell'elenco nel tuo profilo di riferimento, recupera FullyDrawnReporter utilizzando getFullyDrawnReporter e aggiungi un reporter nel codice dell'app. Rilascia il reporter una volta che l'attività in background ha completato la compilazione dell'elenco. FullyDrawnReporter non chiama il metodo reportFullyDrawn finché non vengono rilasciati tutti i reporter. In questo modo, il profilo Baseline include i percorsi del codice necessari per compilare l'elenco. In questo modo, il comportamento dell'app non cambia per l'utente, ma il profilo di riferimento può includere tutti i percorsi del codice necessari.

Per indicare lo stato di disegno completo, utilizza le seguenti API di Compose:

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