Basisprofile erstellen

Mit der Jetpack MacroBenchmark-Bibliothek und BaselineProfileRule lassen sich für jeden App-Release automatisch Profile generieren. Wir empfehlen die Verwendung von com.android.tools.build:gradle:8.0.0 oder höher, da bei der Verwendung von Baseline-Profilen Verbesserungen bei der Build-Ausführung erzielt werden.

So erstellen Sie ein neues Baseline-Profil:

  1. Richten Sie das Modul „Baseline-Profil“ ein.
  2. Definieren Sie den JUnit-Test, mit dem Baseline-Profile generiert werden.
  3. Fügen Sie die kritischen User Journeys hinzu, die Sie optimieren möchten.
  4. Erstellen Sie das Baseline-Profil.

Nachdem Sie das Baseline-Profil erstellt haben, führen Sie einen Benchmark mit einem physischen Gerät durch, 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 Plugin (AGP) 8.2 verfügbar ist.

Mit der Modulvorlage „Baseline Profile Generator“ von Android Studio wird das Erstellen eines neuen Moduls zum Generieren und Benchmarken von Baseline-Profilen automatisiert. Wenn Sie die Vorlage ausführen, werden die meisten der typischen Buildkonfigurationen, die Baseline-Profilgenerierung und der Bestätigungscode generiert. Mit der Vorlage wird Code erstellt, um Baseline-Profile zu generieren und zu vergleichen, um das Starten der App 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-Profilgenerator aus und konfigurieren Sie sie:
    Abbildung 1 Vorlage für das Modul „Baseline Profile Generator“.

    Die Vorlage enthält die folgenden Felder:

    • Zielanwendung: definiert, für welche App das Referenzprofil generiert wird. Wenn Ihr Projekt nur ein App-Modul enthält, ist nur ein Element in dieser Liste zu sehen.
    • Modulname: Der gewünschte Name für das zu erstellende Baseline-Profil-Modul.
    • Paketname: Der gewünschte Paketname für das Baseline-Profil-Modul.
    • Sprache: Gibt an, ob der generierte Code Kotlin oder Java sein soll.
    • Build-Konfigurationssprache: Hier können Sie auswählen, ob Sie Kotlin Script (KTS) oder Groovy für Ihre Build-Konfigurationsscripts 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, um das neue Modul zu erstellen. Wenn Sie die Versionsverwaltung verwenden, werden Sie möglicherweise aufgefordert, die neu erstellten Moduldateien der Versionsverwaltung hinzuzufügen.

Generator für Baseline-Profile definieren

Das neu erstellte Modul enthält Tests zum Generieren und Benchmarking des Referenzprofils sowie zum Testen des einfachen App-Starts. 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 = true enthalten sind. Um eine optimale Leistung zu erzielen, sollten alle Tests, die sich nicht auf den App-Start beziehen, nicht in einem Startprofil enthalten sein. Mit App-Startoptimierungen wird ein spezieller Teil eines Baseline-Profils definiert, das Startprofil.

Für die Wartbarkeit ist es hilfreich, diese CUJs außerhalb des generierten Baseline-Profils und des Benchmark-Codes zu abstrahieren, damit sie für beide verwendet werden können. Das bedeutet, dass Änderungen an Ihren CUJs einheitlich verwendet werden.

Basisprofil generieren und installieren

Mit der Vorlage für das Baseline-Profil-Modul wird eine neue Ausführungskonfiguration hinzugefügt, um das Baseline-Profil zu generieren. 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 „Referenzprofil generieren“
Abbildung 2: Durch Ausführen dieser Konfiguration wird das Baseline-Profil generiert.

Wenn die Ausführungskonfiguration Baseline-Profil generieren 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 mit dem Release-Build-Typ.

Das generierte Baseline-Profil wurde ursprünglich in build/outputs erstellt. Der vollständige Pfad wird durch die Variante oder den Flavor der App bestimmt, die profiliert wird, und davon, ob Sie für das Profiling ein von Gradle verwaltetes Gerät oder ein verbundenes Gerät verwenden. Wenn Sie die Namen verwenden, die vom Code verwendet werden, und die Build-Konfigurationen, die von der Vorlage generiert wurden, 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 das Baseline-Profil nicht verwenden können, verwenden Sie die Modulvorlage für den Makrobenchmark und das Gradle-Plug-in für das Baseline-Profil, um ein neues Baseline-Profil zu erstellen. Wir empfehlen die Verwendung dieser Tools ab Android Studio Giraffe und AGP 8.1.

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 auch Interaktionen mit Ihrer App enthalten, die über den App-Start hinausgehen. Auf diese Weise kannst du die Laufzeitleistung deiner App optimieren, z. B. durch Scrollen von Listen, Ausführen von Animationen und Navigieren in einem Activity. Weitere Beispiele für Tests, bei denen @BaselineProfileRule verwendet wird, um kritische User Journeys zu verbessern.

  3. Fügen Sie das Gradle-Plug-in für Baseline-Profile (libs.plugins.androidx.baselineprofile) hinzu. Mit dem Plug-in lassen sich Baseline-Profile leichter generieren und in Zukunft verwalten.

  4. Führen Sie zum Generieren des Baseline-Profils die Gradle-Aufgaben :app:generateBaselineProfile oder :app:generateVariantBaselineProfile im Terminal aus.

    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 Generator des Baseline-Profils Root-Zugriff benötigen.

    Am Ende der Generierungsaufgabe wird das Baseline-Profil in app/src/variant/generated/baselineProfiles kopiert.

Neues Baseline-Profil ohne Vorlagen erstellen

Wir empfehlen, ein Baseline-Profil mit der Vorlage für das Baseline-Profil (bevorzugt) oder der Vorlage für MacroBenchmark von Android Studio zu erstellen. Sie können aber auch das Gradle-Plug-in für Baseline-Profile 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 Gradle-Plug-in für Baseline-Profile:

  1. Erstellen Sie ein neues com.android.test-Modul, z. B. :baseline-profile.
  2. Konfigurieren Sie die build.gradle.kts-Datei 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 GMD 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 im Testmodul :baseline-profile einen Test für das Baseline-Profil. Im folgenden Beispiel wird die App gestartet und auf Inaktivität gewartet.

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

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

Neues Baseline-Profil mit AGP 7.3–7.4 erstellen

Es ist möglich, Baseline-Profile mit AGP 7.3–7.4 zu generieren. Wir empfehlen jedoch dringend, auf mindestens AGP 8.1 umzustellen, damit Sie das Baseline Profile Gradle-Plug-in und seine neuesten Funktionen verwenden können.

Wenn Sie mit AGP 7.3–7.4 Baseline-Profile erstellen möchten, sind die Schritte mit Ausnahme der folgenden Punkte mit denen für AGP 8.1 identisch:

Generierte Regeln manuell anwenden

Der Generator für das Baseline-Profil erstellt eine HRF-Textdatei (Human Readable Format) auf dem Gerät und kopiert sie auf Ihren Hostcomputer. So wenden Sie das generierte Profil auf Ihren Code an:

  1. Suchen Sie die HRF-Datei im Build-Ordner des Moduls, in dem Sie das Profil generieren:[module]/build/outputs/managed_device_android_test_additional_output/[device].

    Profile folgen dem Namensmuster [class name]-[test method name]-baseline-prof.txt, das so aussieht: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. Kopieren Sie das generierte Profil in src/main/ und benennen Sie die Datei in baseline-prof.txt um.

  3. Fügen Sie in der build.gradle.kts-Datei Ihrer App eine Abhängigkeit zur ProfileInstaller-Bibliothek hinzu, um die lokale Baseline-Profilkompilierung zu aktivieren, wenn Cloud-Profile nicht verfügbar sind. Dies ist die einzige Möglichkeit, ein Baseline-Profil lokal zu sideloaden.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. Erstellen Sie die Produktionsversion Ihrer App, während die angewendeten HRF-Regeln in Binärform kompiliert und in das APK oder AAB aufgenommen werden. Vertreiben Sie Ihre App dann wie gewohnt.

Baseline-Profil als Benchmark verwenden

Um einen Benchmark für Ihr Baseline-Profil zu erstellen, erstellen Sie über die Aktion in der Seitenleiste eine neue Konfiguration für Android-Instrumented-Tests, mit der die in der Datei StartupBenchmarks.kt oder StartupBencharks.java definierten Benchmarks ausgeführt werden. Weitere Informationen zu Benchmark-Tests finden Sie unter Macrobenchmark-Klasse erstellen und Messung mit der Macrobenchmark-Bibliothek automatisieren.

Abbildung 3: Android-Tests über die Aktion im Bereich „Gutter“ ausführen.

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

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:

Zeit bis zur ersten Anzeige (Time to initial display, TTID)
Die Zeit, die vergeht, bis der erste Frame der App-Benutzeroberfläche angezeigt wird.
Zeit bis zur vollständigen Anzeige (Time to Full Display, TTFD)
TTID plus die Zeit, die zum Anzeigen von Inhalten benötigt wird, die nach dem ersten Frame asynchron geladen werden.

Die TTFD wird gemeldet, sobald die Methode reportFullyDrawn() des ComponentActivity aufgerufen wird. Wenn reportFullyDrawn() nie aufgerufen wird, wird stattdessen die TTID erfasst. Möglicherweise müssen Sie den Aufruf von reportFullyDrawn() verzögern, bis das asynchrone Laden abgeschlossen ist. Wenn die Benutzeroberfläche beispielsweise eine dynamische Liste wie eine RecyclerView oder eine Lazy-Liste enthält, wird die Liste möglicherweise durch eine Hintergrundaufgabe gefüllt, die 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 ist Code, der ausgeführt wird, nachdem die Benutzeroberfläche vollständig gezeichnet wurde, nicht im Baseline-Profil enthalten.

Wenn Sie die Liste in Ihr Baseline-Profil aufnehmen möchten, rufen Sie FullyDrawnReporter mit getFullyDrawnReporter() ab und fügen Sie im App-Code einen Berichter hinzu. Lassen Sie den Berichter frei, sobald die Liste im Hintergrund vollständig erstellt wurde. Der FullyDrawnReporter ruft die reportFullyDrawn()-Methode erst auf, wenn alle Reporter freigegeben wurden. Dadurch enthält das Baseline-Profil die Codepfade, die zum Ausfüllen der Liste erforderlich sind. Dadurch wird das Verhalten der Anwendung für den Nutzer nicht geändert, das Baseline-Profil kann jedoch alle erforderlichen Codepfade enthalten.

Wenn Ihre Anwendung Jetpack Compose verwendet, geben Sie mit den folgenden APIs den vollständig gezeichneten Zustand an:

  • ReportDrawn zeigt an, dass das Composeable sofort für Interaktionen bereit ist.
  • ReportDrawnWhen nimmt ein Prädikat wie list.count > 0 an, um anzugeben, wann das Composeable für Interaktionen bereit ist.
  • ReportDrawnAfter nimmt eine Methode zur Aussetzung an, die nach Abschluss angibt, dass das Composeable für die Interaktion bereit ist.