Basisprofile erstellen

Baseline-Profile sind unerlässlich, um die Leistung von Jetpack Compose zu maximieren. Wenn Sie Ihre kritischen User Journeys vorkompilieren, wird die Compose-Benutzeroberfläche reibungslos gerendert.

Profile für jede App-Version automatisch mit der Jetpack Macrobenchmark-Bibliothek und BaselineProfileRule generieren Wir empfehlen, com.android.tools.build:gradle:8.0.0 oder höher zu verwenden, um von den Verbesserungen bei der Erstellung von Baseline-Profilen zu profitieren.

So erstellen Sie ein neues Baseline-Profil:

  1. Richten Sie das Baseline Profile-Modul ein.
  2. Definieren Sie den JUnit-Test, mit dem Baseline-Profile generiert werden.
  3. Fügen Sie das wichtige Nutzerverhalten (Critical User Journeys, CUJs) hinzu, das Sie optimieren möchten.
  4. Generieren Sie das Baseline-Profil.

Nachdem Sie das Baseline-Profil generiert haben, können Sie es auf einem physischen Gerät testen, um die Geschwindigkeitsverbesserungen zu messen.

Neues Baseline-Profil mit AGP 8.2 oder höher erstellen

Am einfachsten erstellen Sie ein neues Baseline-Profil mit der Modulvorlage für Baseline-Profile, die ab Android Studio Iguana und Android-Gradle-Plug-in (AGP) 8.2 verfügbar ist.

Die Modulvorlage „Android Studio Baseline Profile Generator“ automatisiert die Erstellung eines neuen Moduls zum Generieren und Benchmarking von Baseline-Profilen. Wenn Sie die Vorlage ausführen, wird der Großteil der typischen Build-Konfiguration, der Baseline-Profilgenerierung und des Bestätigungscodes generiert. Die Vorlage erstellt Code zum Generieren und Benchmarking von Baseline-Profilen, um den App-Start zu messen.

Modul „Baseline-Profil“ einrichten

So führen Sie die Modulvorlage für das Baseline-Profil aus:

  1. Wählen Sie Datei > Neu > Neues Modul aus.
  2. Wählen Sie im Bereich Vorlagen die Vorlage Baseline Profile Generator aus und konfigurieren Sie sie:
    Abbildung 1. Modulvorlage für Baseline Profile Generator
    Die Felder in der Vorlage sind die folgenden:
    • Zielanwendung: Die App, für die das Baseline-Profil generiert wird. Wenn Ihr Projekt nur ein App-Modul enthält, ist nur ein Element in dieser Liste vorhanden.
    • Modulname: Der Name, den Sie für das zu erstellende Baseline Profile-Modul verwenden möchten.
    • Paketname: Der Paketname, den Sie für das Baseline Profile-Modul verwenden möchten.
    • Sprache: Gibt an, ob der generierte Code in Kotlin oder Java sein soll.
    • Build configuration language (Sprache für die Build-Konfiguration): Gibt an, ob Sie Kotlin-Script (KTS) oder Groovy für Ihre Build-Konfigurationsskripts verwenden möchten.
    • Von Gradle verwaltetes Gerät verwenden: Gibt an, ob Sie von Gradle verwaltete Geräte zum Testen Ihrer App verwenden.
  3. Klicken Sie auf Fertigstellen. Das neue Modul wird erstellt. Wenn Sie die Versionsverwaltung verwenden, werden Sie möglicherweise aufgefordert, die neu erstellten Moduldateien der Versionsverwaltung hinzuzufügen.

Generator für das Baseline-Profil definieren

Das neu erstellte Modul enthält Tests zum Generieren und Benchmarking des Baseline-Profils sowie Tests, die nur den grundlegenden App-Start testen. Wir empfehlen, diese um CUJs und erweiterte Start-Workflows zu ergänzen. Achten Sie darauf, dass alle Tests, die sich auf den App-Start beziehen, in einem rule-Block mit includeInStartupProfile auf true festgelegt sind. Umgekehrt sollten alle Tests, die sich nicht auf den App-Start beziehen, nicht in einem Startup-Profil enthalten sein, um eine optimale Leistung zu erzielen. App-Startoptimierungen werden verwendet, um einen speziellen Teil eines Baseline-Profils zu definieren, der als Startprofil bezeichnet wird.

Es ist einfacher, den Code zu warten, wenn Sie diese CUJs außerhalb des generierten Baseline-Profils und Benchmark-Codes abstrahieren, damit sie für beide verwendet werden können. Das bedeutet, dass Änderungen an Ihren CUJs einheitlich verwendet werden.

Baseline-Profil generieren und installieren

Mit der Modulvorlage für Baseline-Profile wird eine neue Ausführungskonfiguration zum Generieren des Baseline-Profils hinzugefügt. Wenn Sie Produktvarianten verwenden, erstellt Android Studio mehrere Ausführungskonfigurationen, damit Sie für jede Variante separate Baseline-Profile generieren können.

Die Ausführungskonfiguration „Baseline-Profil generieren“.
Abbildung 2: Wenn Sie diese Konfiguration ausführen, wird das Baseline-Profil generiert.

Wenn die Run-Konfiguration Generate Baseline Profile abgeschlossen ist, wird das generierte Baseline-Profil in die Datei src/variant/generated/baselineProfiles/baseline-prof.txt im zu profilierenden Modul kopiert. Die Variantenoptionen sind entweder der Release-Build-Typ oder eine Build-Variante, die den Release-Build-Typ umfasst.

Das generierte Baseline-Profil wird ursprünglich in build/outputs erstellt. Der vollständige Pfad hängt von der Variante oder Version der zu profilierenden App und davon ab, ob Sie ein von Gradle verwaltetes Gerät oder ein verbundenes Gerät für die Profilerstellung verwenden. Wenn Sie die Namen verwenden, die vom Code und den Build-Konfigurationen der Vorlage verwendet werden, wird das Baseline-Profil in der Datei build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt erstellt. Sie müssen wahrscheinlich nicht direkt mit dieser Version des generierten Baseline-Profils interagieren, es sei denn, Sie kopieren es manuell in die Zielmodule (nicht empfohlen).

Neues Baseline-Profil mit AGP 8.1 erstellen

Wenn Sie die Modulvorlage für Baseline-Profile nicht verwenden können, verwenden Sie die Modulvorlage für Macrobenchmark und das Baseline-Profil-Gradle-Plug-in, um ein neues Baseline-Profil zu erstellen. Wir empfehlen, diese Tools ab Android Studio Giraffe und AGP 8.1 zu verwenden.

So erstellen Sie ein neues Baseline-Profil mit der Macrobenchmark-Modulvorlage und dem Baseline-Profil-Gradle-Plug-in:

  1. Richten Sie ein Macrobenchmark-Modul in Ihrem Gradle-Projekt ein.
  2. Definieren Sie eine neue Klasse mit dem Namen BaselineProfileGenerator:

    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }
    

    Der Generator kann Interaktionen mit Ihrer App enthalten, die über den App-Start hinausgehen. So können Sie die Laufzeitleistung Ihrer App optimieren, z. B. beim Scrollen von Listen, Ausführen von Animationen und Navigieren in einem Activity. Weitere Beispiele für Tests, bei denen @BaselineProfileRule verwendet wird, um wichtige Nutzeraktionen zu optimieren

  3. Fügen Sie das Baseline-Profil-Gradle-Plug-in (libs.plugins.androidx.baselineprofile) hinzu. Das Plug-in erleichtert das Generieren und Verwalten von Baseline-Profilen.

  4. Führen Sie die Gradle-Aufgaben :app:generateBaselineProfile oder :app:generateVariantBaselineProfile im Terminal aus, um das Baseline-Profil zu generieren.

    Führen Sie den Generator als instrumentierten Test auf einem gerooteten physischen Gerät, einem Emulator oder einem von Gradle verwalteten Gerät aus. Wenn Sie ein von Gradle verwaltetes Gerät verwenden, legen Sie aosp als systemImageSource fest, da Sie für den Baseline Profile-Generator Root-Zugriff benötigen.

    Am Ende des Generierungsvorgangs wird das Baseline-Profil in app/src//generated/baselineProfiles kopiert.

Neues Baseline-Profil ohne Vorlagen erstellen

Wir empfehlen, ein Baseline-Profil mit der Modulvorlage für Baseline-Profile (bevorzugt) oder der Macrobenchmark-Vorlage von Android Studio zu erstellen. Sie können aber auch nur das Baseline-Profil-Gradle-Plug-in verwenden. Weitere Informationen zum Gradle-Plug-in für Baseline-Profile finden Sie unter Generierung von Baseline-Profilen konfigurieren.

So erstellen Sie ein Baseline-Profil direkt mit dem Baseline-Profil-Gradle-Plug-in:

  1. Erstellen Sie ein neues com.android.test-Modul, z. B. :baseline-profile.
  2. Konfigurieren Sie die Datei build.gradle.kts für :baseline-profile:

    1. Wenden Sie das androidx.baselineprofile-Plug-in an.
    2. Achten Sie darauf, dass targetProjectPath auf das Modul :app verweist.
    3. Optional können Sie ein von Gradle verwaltetes Gerät hinzufügen. Im folgenden Beispiel ist das pixel6Api31. Wenn keine Angabe erfolgt, verwendet das Plug-in ein verbundenes Gerät, entweder emuliert oder physisch.
    4. Wenden Sie die gewünschte Konfiguration an, wie im folgenden Beispiel gezeigt.

    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. Erstellen Sie einen Baseline-Profil-Test im Testmodul :baseline-profile. Das folgende Beispiel zeigt einen Test, der ein Baseline-Profil für den App-Start generiert.

        class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                uiAutomator { startApp(PACKAGE_NAME) }
            }
        )
    }
    
  4. Aktualisieren Sie die Datei build.gradle.kts im App-Modul, z. B. :app.

    1. Wenden Sie das Plug-in androidx.baselineprofile an.
    2. Fügen Sie dem Modul :baseline-profile eine baselineProfile-Abhängigkeit hinzu.

    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. Generieren Sie das Profil, indem Sie die Gradle-Aufgaben :app:generateBaselineProfile oder :app:generateVariantBaselineProfile ausführen.

  6. Am Ende des Generierungsvorgangs wird das Baseline-Profil in app/src/variant/generated/baselineProfiles kopiert.

Baseline-Profil benchmarken

Um Ihr Baseline-Profil zu vergleichen, erstellen Sie über die Gutter-Aktion eine neue Konfiguration für den instrumentierten Android-Testlauf, mit der die in der Datei StartupBenchmarks.kt definierten Benchmarks ausgeführt werden. Weitere Informationen zu Benchmarktests finden Sie unter Macrobenchmark-Klasse erstellen und Baseline-Profile mit der Macrobenchmark-Bibliothek testen.

Abbildung 3: Android-Tests über die Aktion Run Android Tests from the gutter ausführen.

Wenn Sie diesen Befehl in Android Studio ausführen, enthält die Build-Ausgabe Details zu den Geschwindigkeitsverbesserungen, die das Baseline-Profil bietet:

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

Alle erforderlichen Codepfade erfassen

Die beiden wichtigsten Messwerte für die Startzeit von Apps sind:

TTFD wird gemeldet, sobald die Methode reportFullyDrawn des ComponentActivity aufgerufen wird. Wenn reportFullyDrawn nie aufgerufen wird, wird stattdessen die TTID gemeldet. Möglicherweise müssen Sie den Aufruf von reportFullyDrawn verzögern, bis das asynchrone Laden abgeschlossen ist. Wenn die Benutzeroberfläche beispielsweise eine dynamische Lazy List enthält, wird die Liste möglicherweise durch eine Hintergrundaufgabe gefüllt, die erst abgeschlossen wird, nachdem die Liste zum ersten Mal gezeichnet wurde und die Benutzeroberfläche daher als vollständig gezeichnet markiert wurde. In solchen Fällen wird Code, der ausgeführt wird, nachdem die Benutzeroberfläche vollständig gerendert wurde, nicht in das Baseline-Profil aufgenommen.

Wenn Sie die Listenerstellung in Ihr Baseline-Profil einbeziehen möchten, rufen Sie die FullyDrawnReporter mit getFullyDrawnReporter ab und fügen Sie in Ihrem App-Code einen Reporter hinzu. Geben Sie den Reporter frei, sobald die Hintergrundaufgabe abgeschlossen ist. Die FullyDrawnReporter-Methode ruft die reportFullyDrawn-Methode erst auf, wenn alle Reporter freigegeben wurden. Dadurch enthält das Baseline-Profil die Codepfade, die zum Füllen der Liste erforderlich sind. Das Verhalten der App für den Nutzer ändert sich dadurch nicht, aber das Baseline-Profil kann alle erforderlichen Codepfade enthalten.

Verwenden Sie die folgenden Compose-APIs, um den Status „vollständig gezeichnet“ anzugeben:

  • ReportDrawn gibt an, dass das Composable sofort für die Interaktion bereit ist.
  • ReportDrawnWhen verwendet ein Prädikat wie list.count > 0, um anzugeben, wann Ihr Composable für die Interaktion bereit ist.
  • ReportDrawnAfter verwendet eine suspendierende Methode, die nach Abschluss angibt, dass das Composable für die Interaktion bereit ist.