Omówienie profili podstawowych

Profile bazowe zwiększają szybkość wykonywania kodu o około 30% w porównaniu z pierwszym uruchomieniem, ponieważ unikają interpretacji i czynności kompilacji w czasie wykonywania (JIT) w przypadku uwzględnionych ścieżek kodu.

Dzięki udostępnieniu profilu bazowego w aplikacji lub bibliotece środowisko uruchomieniowe Android (ART) może optymalizować określone ścieżki kodu za pomocą kompilacji z wyprzedzeniem (AOT), co zapewnia poprawę wydajności dla każdego nowego użytkownika i każdej aktualizacji aplikacji. Optymalizacja na podstawie profilu (PGO) umożliwia aplikacjom optymalizację uruchamiania, zmniejszenie opóźnień interakcji i poprawę ogólnej wydajności w czasie działania od pierwszego uruchomienia.

Te ulepszenia wydajności bezpośrednio przekładają się na lepsze wyniki biznesowe, takie jak utrzymanie użytkowników, transakcje i oceny. Więcej informacji o tym, jak wyniki wpływają na dane firmy, znajdziesz w historiach z Josh, Lyft, TikTokZomato.

Zalety profili podstawowych

Profile podstawowe sprawiają, że wszystkie interakcje użytkownika – np. uruchamianie aplikacji, poruszanie się między ekranami czy przewijanie treści – przebiegają płynniej od pierwszego uruchomienia. Dzięki zwiększeniu szybkości i czułości aplikacji profile podstawowe mogą zwiększać liczbę aktywnych użytkowników dziennie i średni wskaźnik powrotów.

Profile podstawowe ułatwiają optymalizację poza procesem uruchamiania aplikacji, ponieważ zapewniają typowe interakcje użytkowników, które usprawniają działanie aplikacji już od pierwszego uruchomienia. Prowadzona przez użytkownika kompilacja AOT nie wymaga korzystania z urządzeń użytkowników i może być wykonywana raz na wersję na komputerze deweloperskim, a nie na urządzeniu mobilnym. Dzięki udostępnianiu wersji z profilem bazowym optymalizacje aplikacji są dostępne znacznie szybciej niż w przypadku korzystania tylko z profili w chmurze.

Gdy nie używasz profilu Baseline, cały kod aplikacji jest kompilowany przez JIT w pamięci po zinterpretowaniu lub zapisywany w pliku odex w tle, gdy urządzenie jest bezczynne. Po zainstalowaniu lub zaktualizowaniu aplikacji użytkownicy od razu ją uruchamiają, a jej obsługa nie jest optymalna, aż do zoptymalizowania nowych ścieżek kodu. Wiele aplikacji mierzy wzrost wydajności o około 30% po optymalizacji.

Profile uruchamiania

Profile startowe są podobne do profili podstawowych, ale różnią się tym, że są używane w czasie kompilacji, a nie do optymalizacji na urządzeniu. Profil startowy służy do optymalizacji układu pliku DEX w celu skrócenia czasu uruchamiania. Kod z profilu startowego jest umieszczany w głównym pliku classes.dex, a pozostały kod – w osobnych plikach DEX. Dzięki temu skrócisz czas uruchamiania, zmniejszając liczbę błędów strony podczas uruchamiania aplikacji. Więcej informacji o tym, jak profile uruchamiania i optymalizacje układu DEX mogą skrócić czas uruchamiania aplikacji, znajdziesz w artykule Optymalizacje układu DEX i profile uruchamiania.

Rozpocznij

Aby zacząć optymalizować działanie istniejącej aplikacji, zapoznaj się z artykułem Tworzenie profili bazowych.

Łańcuch zależności zapewnia wersje stabilne i rozwojowe. Aby wygenerować i zainstalować profil referencyjny, użyj tych obsługiwanych wersji lub nowszych wtyczki Android Gradle, biblioteki Macrobenchmark i instalatora profilu. Te zależności są wymagane w różnych momentach i działają razem jako zestaw narzędzi, aby umożliwić optymalny profil podstawowy.

  • Wtyczka Androida do obsługi Gradle: com.android.tools.build:8.0.0
  • Biblioteka makrobenchmarków:androidx.benchmark:benchmark-macro-junit4:1.3.3
  • Instalator profilu: androidx.profileinstaller:profileinstaller:1.4.1

Do tworzenia profili referencyjnych i zarządzania nimi zalecamy korzystanie z najnowszej wersji AGP. Oto główne funkcje dostępne w różnych wersjach AGP:

Wersja AGP Funkcje
8.4 Lokalne instalacje aplikacji z kompilacji, których nie można debugować, za pomocą narzędzia wiersza poleceń Gradle lub zainstalowanych profili podstawowych w Android Studio, dzięki czemu wydajność lokalnej kompilacji wersji jest bardziej zgodna z wydajnością w środowisku produkcyjnym. Ta aktualizacja nie wpływa na skuteczność profili referencyjnych w środowisku produkcyjnym.
8.3
  • Obsługa katalogów z pełnym zestawem źródeł (moduły bibliotek): zadeklaruj wiele plików źródłowych profilu Baseline i zastosuj katalogi uwzględniające warianty, np. src/free/generated/baselineProfiles/baseline-prof1.txt, w zarówno modułach bibliotek, jak i modułach aplikacji.
  • Profile podstawowe obejmują klasy bez cukru.
8.2
  • Przepisywanie reguł R8: D8 i R8 mogą przekształcać zrozumiałe dla człowieka reguły bazowe i profilu startowego tak, aby w pełni rejestrować wszystkie reguły potrzebne do optymalizacji wydajności aplikacji. Zwiększa zasięg metod w profilu podstawowym o ok. 30% i skuteczność aplikacji o ok. 15%.
  • Profile startowe: wygeneruj nowy typ profilu Baseline, aby zapewnić układ kodu w DEX. Zwiększa wydajność uruchamiania o dodatkowe ~15% lub znacznie więcej w przypadku dużych aplikacji.
z Androidem 8.0 Minimalna zalecana wersja: użyj wtyczki Gradle do generowania profili referencyjnych za pomocą pojedynczego zadania Gradle.
  • Obsługa pełnego katalogu zbioru źródeł (moduły aplikacji): zadeklaruj kilka plików źródłowych profilu podstawowego i użyj katalogów obsługujących warianty, takich jak src/free/generated/baselineProfiles/baseline-prof1.txt.
7.4 Minimalna obsługiwana wersja: aplikacje mogą korzystać z profili podstawowych z bibliotek i udostępniać własny profil bazowy w pliku src/main/baseline-prof.txt.
  • Podczas tworzenia pliku APK na podstawie pakietu aplikacji profile podstawowe są prawidłowo spakowane (problem nr 230361284).
  • W przypadku aplikacji, które mają więcej niż 1 plik .dex, profile podstawowe są prawidłowo spakowane dla podstawowego pliku .dex.

Przykład generowania profilu

Poniżej znajduje się przykładowa klasa do tworzenia profilu podstawowego na potrzeby uruchamiania aplikacji, a także kilka zdarzeń nawigacji i przewijania z zalecaną biblioteką Macrobenchmark:

@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun appStartupAndUserJourneys() {
        baselineProfileRule.collect(packageName = PACKAGE_NAME) {
            // App startup journey.
            startActivityAndWait()

            device.findObject(By.text("COMPOSE LAZYLIST")).clickAndWait(Until.newWindow(), 1_000)
            device.findObject(By.res("myLazyColumn")).also {
                it.fling(Direction.DOWN)
                it.fling(Direction.UP)
            }
            device.pressBack()
        }
    }
}

Ten kod wraz z pełnym kontekstem i dodatkowymi informacjami znajdziesz w przykładach kodu na GitHubie.

Co uwzględnić?

Korzystając z profili bazowych w aplikacji, możesz uwzględnić kod uruchamiania aplikacji i typowe interakcje z użytkownikiem, takie jak nawigacja między ekranami czy przewijanie. Możesz też zbierać dane z całych procesów, takich jak rejestracja, logowanie czy płatności. Profile podstawowe mogą poprawić wydajność w czasie działania dowolnej ścieżki użytkownika, która jest dla Ciebie kluczowa.

Jeśli eksperymentujesz z różnymi sposobami zwiększania skuteczności, rozważ uwzględnienie profili podstawowych w obu grupach eksperymentu. Dzięki temu wyniki będą łatwiejsze do interpretacji, ponieważ wszyscy użytkownicy będą uruchamiać skompilowany kod.

Biblioteki mogą udostępniać własne profile bazowe i przesyłać je wraz z wersjami, aby poprawić wydajność aplikacji. Przykładem może być sekcja Używanie profilu bazowego w Jetpack Compose.

Jak działają profile podstawowe

Podczas tworzenia aplikacji lub biblioteki rozważ zdefiniowanie profili bazowych, aby uwzględnić typowe interakcje użytkowników, w przypadku których czas renderowania lub opóźnienie są ważne. Działa to w następujący sposób:

  1. W aplikacji są generowane czytelne dla człowieka reguły profilu, które są kompilowane w aplikacji w postaci binarnej. Znajdziesz je w pliku assets/dexopt/baseline.prof. Następnie możesz przesłać AAB do Google Play w zwykły sposób.

  2. Google Play przetwarza profil i przesyła go bezpośrednio do użytkowników wraz z pakietem APK. Podczas instalacji ART przeprowadza kompilację AOT metod w profilu, co przyspiesza ich działanie. Jeśli profil zawiera metody używane podczas uruchamiania aplikacji lub renderowania klatek, użytkownik może zauważyć szybsze uruchamianie i mniejsze zacięcia.

  3. Ten proces współpracuje z zbiorczym raportem Cloud Profiles, aby dostosowywać wydajność na podstawie rzeczywistego użytkowania aplikacji w czasie.

Rysunek 1. Ten diagram pokazuje przepływ pracy dotyczący profilu referencyjnego od przesłania do dostarczenia użytkownikowi końcowemu oraz jego powiązanie z profilami w chmurze.

Profile w Google Cloud

Profile w chmurze stanowią dodatkową formę PGO – są agregowane przez Google Play Store i rozprowadzane w ramach kompilacji w czasie instalacji – razem z Profilem bazowym.

Chociaż profile w Cloud są tworzone na podstawie rzeczywistych interakcji użytkowników z aplikacją, ich dystrybucja zajmuje od kilku godzin do kilku dni, co ogranicza ich dostępność. Dopóki profile nie zostaną w pełni rozpowszechnione, wydajność aplikacji będzie nieoptymalna dla użytkowników nowych lub zaktualizowanych aplikacji. Co więcej, Profile w chmurze obsługują tylko urządzenia z Androidem w wersji 9 (poziom interfejsu API 28) lub nowszej i skalują się tylko w przypadku aplikacji, które mają wystarczająco dużą bazę użytkowników.

Kompilowanie w różnych wersjach Androida

Różne wersje platformy Androida korzystają z różnych metod kompilacji aplikacji, z których każda ma odpowiedni kompromis pod względem wydajności. Profile bazowe są lepsze od poprzednich metod kompilacji, ponieważ zawierają profil wszystkich instalacji.

Wersja Androida Metoda kompilacji Podejście do optymalizacji
5–6 (poziom API 21–23) Pełne AOT Podczas instalacji cała aplikacja jest optymalizowana, co wydłuża czas oczekiwania na korzystanie z aplikacji, zwiększa wykorzystanie pamięci RAM i miejsca na dysku oraz wydłuża czas wczytywania kodu z dysku, co może wydłużyć czas uruchamiania aplikacji „na zimno”.
7 do 8.1 (poziom interfejsu API 24 do 27) Częściowy AOT (profil podstawowy) Profile podstawowe są instalowane przez androidx.profileinstaller przy pierwszym uruchomieniu, gdy moduł aplikacji definiuje tę zależność. ART może jeszcze bardziej to usprawnić, dodając kolejne reguły profilu podczas korzystania z aplikacji i kompilując je, gdy urządzenie jest bezczynne. Pozwala to zoptymalizować wykorzystanie miejsca na dysku i czas wczytywania kodu z dysku, co skraca czas oczekiwania na uruchomienie aplikacji.
9 (poziom 28 interfejsu API) lub wyższy Częściowy AOT (punkt odniesienia + profil w Google Cloud) Podczas instalowania aplikacji Google Play używa profili podstawowych do optymalizowania plików APK i profilów w chmurze (jeśli są dostępne). Po zainstalowaniu aplikacja przesyła profile do Google Play, agreguje je, a następnie udostępnia jako profile w chmurze innym użytkownikom, gdy instalują lub aktualizują aplikację.

Znane problemy

Poniżej znajdziesz możliwe problemy i ich rozwiązania lub problemy, w przypadku których trwają prace nad obejściem:

  • Generowanie profilu podstawowego może się nie udać z powodu ustawień uprawnień na niektórych urządzeniach, w tym na urządzeniach OnePlus. Aby obejść ten problem, wyłącz opcję Wyłącz monitorowanie uprawnień w ustawieniach Opcji programisty.

  • Generowanie profilu podstawowego nie jest obsługiwane na urządzeniach Laboratorium Firebase, w tym na urządzeniach zarządzanych przez Gradle (problem 285187547).

  • Aby poprawnie udostępnić profile bazowe do bibliotek, użyj co najmniej wtyczki do obsługi Gradle profilu Baseline w wersji 1.2.3 lub AGP w wersji 8.3 (numer problemu 313992099).

  • Jeśli wygenerujesz profile bazowe za pomocą polecenia ./gradlew app:generateBaselineProfile, punkty odniesienia w module testowym zostaną również uruchomione, a ich wyniki zostaną odrzucone. W takim przypadku możesz wygenerować tylko profile referencyjne, wykonując polecenie z opcją -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile. Ten problem został rozwiązany w AGP 8.2.

  • Polecenie służące do generowania profili podstawowych dla wszystkich typów kompilacji (./gradlew app:generateBaselineProfile) generuje profile podstawowe tylko dla kompilacji wersji. Ten problem został rozwiązany w wersji AGP 8.1.

  • Kanały dystrybucji aplikacji inne niż Sklep Google Play mogą nie obsługiwać profili podstawowych podczas instalacji. Użytkownicy aplikacji zainstalowanych za pomocą tych kanałów nie widzą korzyści, dopóki nie zostanie uruchomiony dexopt w tle, co prawdopodobnie nastąpi w nocy.

  • Udostępnianie aplikacji w Sklepie Play nie obsługuje profili podstawowych, ale ścieżka testu wewnętrznego już tak.

  • Optymalizacja baterii na niektórych urządzeniach, na przykład na urządzeniach Huawei, może zakłócać instalację profilu. Aby mieć pewność, że profile są skutecznie instalowane, na urządzeniach testowych wyłącz wszelkie optymalizacje baterii.

Dodatkowe materiały