Creare profili di riferimento

I profili di baseline sono essenziali per massimizzare il rendimento di Jetpack Compose. La precompilazione dei percorsi utente critici contribuisce a garantire il rendering fluido dell'interfaccia utente di Compose.

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 baseline.

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

  1. Configura il modulo del profilo di baseline.
  2. Definisci il test JUnit che aiuta a generare i profili di baseline.
  3. Aggiungi i percorsi utente critici che vuoi ottimizzare.
  4. Genera il profilo di baseline.

Dopo aver generato il profilo di baseline, esegui il benchmark utilizzando un dispositivo fisico per misurare i miglioramenti della velocità.

Creare un nuovo profilo di baseline con AGP 8.2 o versioni successive

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

Il modello di modulo del generatore di profili di baseline di Android Studio automatizza la creazione di un nuovo modulo per generare ed eseguire il benchmark dei profili di baseline. L'esecuzione del modello genera la maggior parte della configurazione di build tipica, la generazione del profilo di baseline e il codice di verifica. Il modello crea codice per generare ed eseguire il benchmark dei profili di baseline per misurare l'avvio dell'app.

Configurare il modulo del profilo di baseline

Per eseguire il modello di modulo del profilo di baseline:

  1. Seleziona File > Nuovo > Nuovo modulo.
  2. Seleziona il Generatore di profili di baseline modello nel Modelli riquadro e configurarlo:
    Figura 1. Modello di modulo del generatore di profili di baseline.
    I campi del modello sono i seguenti:
    • Applicazione di destinazione: l'app per cui viene generato il profilo di baseline. Se nel progetto è presente un solo modulo dell'app, nell'elenco è presente un solo elemento.
    • Nome modulo: il nome che vuoi assegnare al modulo del profilo di baseline che stai creando.
    • Nome pacchetto: il nome del pacchetto che vuoi assegnare al modulo del profilo di baseline.
    • Lingua: se vuoi che il codice generato sia Kotlin o Java.
    • Lingua di configurazione della build: se vuoi utilizzare Kotlin Script (KTS) o Groovy per gli script di configurazione della build.
    • Utilizza il dispositivo gestito da Gradle: se utilizzi dispositivi gestiti da Gradle per testare l'app.
  3. Fai clic su Fine per creare il nuovo modulo. Se utilizzi il controllo del codice sorgente, potrebbe esserti chiesto di aggiungere i file del modulo appena creato al controllo del codice sorgente.

Definire il generatore di profili di baseline

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

Per una migliore gestibilità, ti consigliamo di astrarre questi percorsi utente critici al di fuori del profilo di baseline generato e del codice di benchmark in modo che possano essere utilizzati per entrambi. Ciò significa che le modifiche ai percorsi utente critici vengono utilizzate in modo coerente.

Generare e installare il profilo di baseline

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

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

Al termine della configurazione di esecuzione Genera profilo di baseline, il profilo di baseline generato viene copiato nel src/variant/generated/baselineProfiles/baseline-prof.txt file nel modulo di cui è stato eseguito il profiling. Le opzioni di variante sono il tipo di build di release o una variante di build che coinvolge il tipo di build di release.

Il profilo di baseline generato viene creato originariamente in build/outputs. Il percorso completo è determinato dalla variante o dalla variante dell'app di cui è stato eseguito il profiling e dal fatto che tu utilizzi un dispositivo gestito da Gradle o un dispositivo connesso per il profiling. Se utilizzi i nomi utilizzati dal codice e dalle configurazioni di build generati dal modello, il profilo di baseline 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 baseline generato, a meno che tu non lo stia copiando manualmente nei moduli di destinazione (non consigliato).

Creare un nuovo profilo di baseline con AGP 8.1

Se non riesci a utilizzare il modello di modulo del profilo di baseline, utilizza il modello di modulo Macrobenchmark e il plug-in Gradle del profilo di baseline per creare un nuovo profilo di 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 di baseline utilizzando il modello di modulo Macrobenchmark e il plug-in Gradle del profilo di 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 l'app oltre all'avvio dell'app. In questo modo puoi ottimizzare il rendimento di runtime dell'app, ad esempio lo scorrimento degli elenchi, l'esecuzione delle animazioni e la navigazione all'interno di un'Activity. Consulta altri esempi di test che utilizzano @BaselineProfileRule per migliorare i percorsi utente critici.

  3. Aggiungi il plug-in Gradle del profilo di baseline (libs.plugins.androidx.baselineprofile). Il plug-in semplifica la generazione e la manutenzione dei profili di baseline in futuro.

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

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

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

Creare un nuovo profilo di baseline senza modelli

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

Ecco come creare un profilo di baseline utilizzando direttamente il plug-in Gradle del profilo 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. (Facoltativo) 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
    }

    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 baseline nel modulo di test :baseline-profile. L'esempio seguente è un test che genera un profilo di baseline 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 baseline viene copiato in app/src/variant/generated/baselineProfiles.

Eseguire il benchmark del profilo di baseline

Per eseguire il benchmark del profilo di baseline, crea una nuova configurazione di esecuzione del test strumentato Android dall'azione della barra di scorrimento che esegue i benchmark definiti nel file StartupBenchmarks.kt. Per saperne di più sui test di benchmark, consulta Creare una classe Macrobenchmark ed Eseguire il benchmark dei profili di baseline con la libreria Macrobenchmark.

Figura 3. Esegui i test Android dall'azione della barra di scorrimento.

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

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

Acquisire tutti i percorsi di codice richiesti

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

Il TTFD viene segnalato 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 l'interfaccia utente contiene un elenco dinamico lazy, l'elenco potrebbe essere popolato da un'attività in background che viene completata dopo il primo disegno dell'elenco e, di conseguenza, dopo che l'interfaccia utente è stata contrassegnata come completamente disegnata. In questi casi, il codice eseguito dopo che l'interfaccia utente raggiunge lo stato completamente disegnato non è incluso nel profilo di baseline.

Per includere la popolazione dell'elenco nel profilo di baseline, recupera il FullyDrawnReporter utilizzando getFullyDrawnReporter e aggiungici un reporter nel codice dell'app. Rilascia il reporter al termine dell'attività in background di popolamento dell'elenco. FullyDrawnReporter non chiama il metodo reportFullyDrawn finché non vengono rilasciati tutti i reporter. In questo modo, il profilo di baseline include i percorsi di codice necessari per popolare l'elenco. Questo non modifica il comportamento dell'app per l'utente, ma consente al profilo di baseline di includere tutti i percorsi di codice necessari.

Per indicare lo stato completamente disegnato, utilizza le seguenti API 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, al termine, indica che il composable è pronto per l'interazione.