Tworzenie profili podstawowych

Automatyczne generowanie profili dla każdej wersji aplikacji za pomocą biblioteki Macrobenchmark JetpackaBaselineProfileRule. Zalecamy korzystanie z wersji com.android.tools.build:gradle:8.0.0 lub nowszej, która zawiera ulepszenia kompilacji przy użyciu profili referencyjnych.

Poniżej znajdziesz ogólne instrukcje tworzenia nowego profilu podstawowego:

  1. Skonfiguruj moduł Baseline Profile.
  2. Zdefiniuj test JUnit, który pomoże wygenerować profile bazowe.
  3. Dodaj główne ścieżki użytkownika, które chcesz zoptymalizować.
  4. Wygeneruj profil podstawowy.

Po wygenerowaniu profilu bazowego przeprowadź test porównawczy na fizycznym urządzeniu, aby zmierzyć poprawę szybkości.

Tworzenie nowego profilu referencyjnego za pomocą AGP 8.2 lub nowszej wersji

Najprostszym sposobem utworzenia nowego profilu bazowego jest użycie szablonu modułu profilu bazowego, który jest dostępny od wersji Android Studio Iguana i Android Gradle Plugin (AGP) 8.2.

Szablon modułu Generatora profili referencyjnych w Android Studio automatyzuje tworzenie nowego modułu służącego do generowania i porównywania profili referencyjnych. Uruchomienie szablonu powoduje wygenerowanie większości typowej konfiguracji kompilacji, profilu podstawowego i kodu weryfikacyjnego. Ten szablon tworzy kod do generowania i testowania porównawczych profili podstawowych w celu pomiaru uruchomienia aplikacji.

Konfigurowanie modułu profilu podstawowego

Aby uruchomić szablon modułu Profil bazowy:

  1. Wybierz File > New > New Module (Plik > Nowy > Nowy moduł)
  2. W panelu Szablony wybierz szablon Generator profilu podstawowego i skonfiguruj go:
    Rysunek 1. Szablon modułu generatora profilu podstawowego.

    Pola w szablonie:

    • Aplikacja docelowa: określa, dla której aplikacji ma być generowany profil podstawowy. Jeśli w projekcie jest tylko 1 moduł aplikacji, na tej liście znajduje się tylko 1 element.
    • Module name (Nazwa modułu): nazwa tworzonego modułu profilu podstawowego.
    • Nazwa pakietu: nazwa pakietu, którą chcesz przypisać do modułu profilu podstawowego.
    • Język: określ, czy wygenerowany kod ma być w języku Kotlin czy Java.
    • Język konfiguracji kompilacji: określ, czy chcesz używać skryptów konfiguracji kompilacji w języku Kotlin Script (KTS) czy Groovy.
    • Używanie urządzenia zarządzanego przez Gradle: określ, czy chcesz używać urządzeń zarządzanych przez Gradle do testowania aplikacji.
  3. Kliknij Gotowe, aby utworzyć nowy moduł. Jeśli korzystasz z kontroli źródła, może pojawić się prośba o dodanie nowo utworzonych plików modułu do kontroli źródła.

Definiowanie generatora profilu podstawowego

Nowo utworzony moduł zawiera testy służące do generowania i porównywania profilu bazowego oraz testowania tylko podstawowego uruchamiania aplikacji. Zalecamy uzupełnienie ich tak, aby obejmowały główne ścieżki konwersji i zaawansowane procesy startupów. Upewnij się, że wszystkie testy związane z uruchamianiem aplikacji znajdują się w bloku rule z wartością includeInStartupProfile równą true. Z kolei, aby zapewnić optymalną wydajność, sprawdź, czy testy niezwiązane z uruchamianiem aplikacji nie są uwzględnione w profilu uruchamiania. Optymalizacje uruchamiania aplikacji służą do definiowania specjalnej części profilu bazowego o nazwie profil uruchamiania.

Aby ułatwić utrzymanie, warto wyodrębnić te dane z wygenerowanego profilu podstawowego i kodu testu porównawczego, aby można było ich używać w obu przypadkach. Oznacza to, że zmiany w CUJ są konsekwentnie stosowane.

Generowanie i instalowanie profilu podstawowego

Szablon modułu profilu podstawowego dodaje nową konfigurację uruchomienia, aby wygenerować profil podstawowy. Jeśli używasz wersji produktu, Android Studio tworzy wiele konfiguracji uruchomienia, aby umożliwić generowanie oddzielnych profili referencyjnych dla każdej wersji.

Konfiguracja uruchomienia generowania profilu podstawowego.
Rysunek 2. Uruchomienie tej konfiguracji spowoduje wygenerowanie profilu Baseline.

Po zakończeniu konfiguracji uruchomienia Generowanie profilu podstawowego wygenerowany profil podstawowy zostanie skopiowany do pliku src/variant/generated/baselineProfiles/baseline-prof.txt w module, który jest profilowany. Opcje wariantów to typ kompilacji wersji lub wariant kompilacji, który wykorzystuje typ kompilacji wersji.

Wygenerowany profil podstawowy został pierwotnie utworzony w zadaniu build/outputs. Pełna ścieżka jest określana na podstawie wariantu lub rodzaju profilowanej aplikacji oraz tego, czy do profilowania używasz urządzenia zarządzanego przez Gradle czy połączonego urządzenia. Jeśli używasz nazw używanych przez kod i konfiguracje kompilacji wygenerowane przez szablon, profil podstawowy zostanie utworzony w pliku build/outputs/managed_device_android_test_additional_output/nonminifiedrelease/pixel6Api31/BaselineProfileGenerator_generate-baseline-prof.txt. Prawdopodobnie nie będzie trzeba bezpośrednio korzystać z tej wersji wygenerowanego profilu podstawowego, chyba że skopiujesz ją ręcznie do modułów docelowych (niezalecane).

Tworzenie nowego profilu referencyjnego za pomocą AGP 8.1

Jeśli nie możesz użyć szablonu modułu profilu referencyjnego, użyj szablonu modułu makrobenchmarku i wtyczki Gradle do profilu referencyjnego, aby utworzyć nowy profil referencyjny. Zalecamy korzystanie z tych narzędzi od wersji Android Studio Giraffe i AGP 8.1.

Oto instrukcje tworzenia nowego profilu referencyjnego za pomocą szablonu modułu Macrobenchmark i wtyczki Gradle do profilu referencyjnego:

  1. Skonfiguruj moduł Macrobenchmark w projekcie Gradle.
  2. Zdefiniuj nową klasę o nazwie BaselineProfileGenerator:
    class BaselineProfileGenerator {
        @get:Rule
        val baselineProfileRule = BaselineProfileRule()
    
        @Test
        fun startup() = baselineProfileRule.collect(
            packageName = "com.example.app",
            profileBlock = {
                startActivityAndWait()
            }
        )
    }

    Generator może zawierać interakcje z Twoją aplikacją poza jej uruchamianiem. Dzięki temu możesz zoptymalizować wydajność aplikacji w czasie działania, np. przewijanie list, uruchamianie animacji i przemieszczanie się w aplikacji.Activity Zobacz inne przykłady testów, które korzystają z funkcji @BaselineProfileRule, aby poprawić najważniejsze ścieżki użytkowników.

  3. Dodaj wtyczkę Gradle do profilu podstawowego (libs.plugins.androidx.baselineprofile). Ułatwia ona generowanie profili podstawowych i ich utrzymywanie w przyszłości.

  4. Aby wygenerować profil Baseline, uruchom w terminalu zadania Gradle :app:generateBaselineProfile lub :app:generateVariantBaselineProfile.

    Uruchom generator jako test zinstruowany na urządzeniu fizycznym z dostępem do roota, emulatorze lub urządzeniu zarządzanym przez Gradle. Jeśli używasz urządzenia zarządzanego przez Gradle, jako aosp ustaw systemImageSource, ponieważ do generatora profilu podstawowego potrzebny jest dostęp root.

    Po zakończeniu zadania generowania profil bazowy jest kopiowany do pliku app/src/variant/generated/baselineProfiles.

Tworzenie nowego profilu podstawowego bez szablonów

Zalecamy utworzenie profilu bazowego za pomocą szablonu modułu profilu bazowego w Android Studio (zalecane) lub szablonu Macrobenchmark, ale możesz też użyć samego wtyczki Gradle do profilu bazowego. Więcej informacji o wtyczce do obsługi Gradle profilu bazowego znajdziesz w artykule o konfigurowaniu generowania profilu podstawowego.

Oto jak utworzyć profil bazowy za pomocą wtyczki Gradle do profilu bazowego:

  1. Utwórz nowy moduł com.android.test, na przykład :baseline-profile.
  2. Skonfiguruj plik build.gradle.kts pod kątem usługi :baseline-profile:

    1. Zastosuj wtyczkę androidx.baselineprofile.
    2. Sprawdź, czy targetProjectPath wskazuje moduł :app.
    3. Opcjonalnie dodaj urządzenie zarządzane przez Gradle (GMD). W tym przykładzie jest to pixel6Api31. Jeśli nie jest to określone, wtyczka używa podłączonego urządzenia, emulowanego lub fizycznego.
    4. Zastosuj wybraną konfigurację, jak pokazano w przykładzie poniżej.

    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
    }

    Odlotowe

    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. Utwórz test profilu podstawowego w module testowym :baseline-profile. Ten przykład to test, który uruchamia aplikację i czeka na stan bezczynności.

    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. Zaktualizuj plik build.gradle.kts w module aplikacji, np. :app.

    1. Zastosuj wtyczkę androidx.baselineprofile.
    2. Dodaj do modułu :baseline-profile zależność baselineProfile.

    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"))
    }

    Odlotowe

    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. Wygeneruj profil, wykonując zadania :app:generateBaselineProfilelub :app:generateVariantBaselineProfile w Gradle.

  6. Po zakończeniu zadania generowania profil bazowy jest kopiowany do pliku app/src/variant/generated/baselineProfiles.

Tworzenie nowego profilu bazowego za pomocą AGP 7.3–7.4

Profile bazowe można generować za pomocą AGP 7.3–7.4, ale zdecydowanie zalecamy przejście na co najmniej AGP 8.1, aby móc korzystać z wtyczki Gradle do tworzenia profili bazowych i jego najnowszych funkcji.

Jeśli musisz utworzyć profile bazowe za pomocą AGP 7.3–7.4, czynności te są takie same jak czynności w AGP 8.1, z tymi wyjątkami:

Ręczne stosowanie wygenerowanych reguł

Generator profili Baseline tworzy na urządzeniu plik tekstowy w formacie HRF (ang. Human Readable Format), i kopiuje go na host. Aby zastosować wygenerowany profil do kodu:

  1. Znajdź plik HRF w folderze kompilacji modułu, w którym został wygenerowany profil: [module]/build/outputs/managed_device_android_test_additional_output/[device].

    Profile są zgodne ze wzorcem nazewnictwa [class name]-[test method name]-baseline-prof.txt, który wygląda tak: BaselineProfileGenerator-startup-baseline-prof.txt.

  2. Skopiuj wygenerowany profil do folderu src/main/ i zmień nazwę pliku na baseline-prof.txt.

  3. Dodaj zależność do biblioteki ProfileInstaller w pliku build.gradle.kts aplikacji, aby umożliwić lokalną kompilację profilu podstawowego, gdy profile w chmurze są niedostępne. Jest to jedyny sposób na lokalne zainstalowanie profilu podstawowego.

    dependencies {
         implementation("androidx.profileinstaller:profileinstaller:1.4.1")
    }
    
  4. Skompiluj wersję produkcyjną aplikacji, gdy zastosowane reguły HRF są skompilowane w postaci binarnej i zawarto je w pliku APK lub AAB. Następnie rozpowszechnij aplikację w zwykły sposób.

Przeprowadź analizę profilu bazowego

Aby przeprowadzić test porównawczy profilu bazowego, utwórz nową konfigurację testu z wykorzystaniem pomiarów z Androida na podstawie działania w rynnie, które wykonuje testy porównawcze zdefiniowane w pliku StartupBenchmarks.kt lub StartupBencharks.java. Więcej informacji o testowaniu porównawczym znajdziesz w artykułach Tworzenie klasy MacrobenchmarkAutomatyzacja pomiarów za pomocą biblioteki Macrobenchmark.

Rysunek 3. Uruchom testy Androida z poziomu ścieżki.

Gdy uruchomisz to w Android Studio, dane wyjściowe kompilacji będą zawierać szczegóły dotyczące ulepszeń szybkości, które zapewnia profil podstawowy:

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

Uwzględnij wszystkie wymagane ścieżki kodu

Oto 2 kluczowe dane związane z mierzeniem czasu uruchamiania aplikacji:

Czas do początkowego wyświetlenia (TTID)
Czas wyświetlania pierwszej klatki interfejsu aplikacji.
Czas do pełnego wyświetlenia (TTFD)
TTID oraz czas wyświetlania treści wczytywanych asynchronicznie po wyświetleniu pierwszej ramki.

Funkcja TTFD jest raportowana po wywołaniu metody reportFullyDrawn() ComponentActivity. Jeśli funkcja reportFullyDrawn() nie zostanie nigdy wywołana, zamiast tego raportowana jest funkcja TTID. Może być konieczne opóźnienie wywołania funkcji reportFullyDrawn() do czasu zakończenia wczytywania asynchronicznego. Jeśli na przykład interfejs zawiera listę dynamiczną, taką jak RecyclerView lub lazylist, może ona być wypełniana przez zadanie w tle, które jest wykonywane po pierwszym narysowaniu listy, a zatem po tym, jak interfejs został oznaczony jako w pełni narysowany. W takich przypadkach kod, który jest wykonywany po osiągnięciu przez interfejs stanu pełnego narysowania, nie jest uwzględniany w profilu bazowym.

Aby uwzględnić populację listy w ramach profilu podstawowego, użyj funkcji FullyDrawnReporter (getFullyDrawnReporter()) i dodaj do niej reportera w kodzie aplikacji. Po zakończeniu wypełniania listy przez zadanie w tle zwróć obiekt reportera. Funkcja FullyDrawnReporter nie wywołuje metody reportFullyDrawn(), dopóki wszyscy reporterzy nie zostaną zwolnieni. Dzięki temu profil bazowy zawiera ścieżki kodu wymagane do wypełnienia listy. Nie zmienia to działania aplikacji dla użytkownika, ale pozwala profilowi bazowemu uwzględnić wszystkie niezbędne ścieżki kodu.

Jeśli Twoja aplikacja korzysta z Jetpack Compose, użyj tych interfejsów API, aby wskazać stan pełnego wyświetlenia:

  • ReportDrawn wskazuje, że komponent jest od razu gotowy do interakcji.
  • ReportDrawnWhen odbiera predykat, np. list.count > 0, aby wskazać, kiedy kompozyt jest gotowy do interakcji.
  • ReportDrawnAfter zawiera metodę zawieszania, która po zakończeniu wskazuje, że kompozyt jest gotowy do interakcji.