Omówienie profili podstawowych

Profile podstawowe przyspieszają wykonywanie kodu o około 30% od pierwszego uruchomienia, ponieważ eliminują etapy interpretacji i kompilacji just-in-time (JIT) w przypadku uwzględnionych ścieżek kodu.

Dzięki profilowi podstawowemu w aplikacji lub bibliotece środowisko wykonawcze Androida (ART) może optymalizować określone ścieżki kodu za pomocą kompilacji AOT, co zwiększa wydajność dla każdego nowego użytkownika i każdej aktualizacji aplikacji. Optymalizacja z użyciem profilu (PGO) pozwala aplikacjom optymalizować uruchamianie, zmniejszać zacięcia interakcji i poprawiać ogólną wydajność środowiska wykonawczego dla użytkowników od pierwszego uruchomienia.

Te ulepszenia wydajności bezpośrednio przekładają się na lepsze wskaźniki biznesowe, takie jak utrzymanie użytkowników, transakcje i oceny. Więcej informacji o tym, jak wydajność wpływa na wskaźniki biznesowe, znajdziesz w artykułach Josh, Lyft, TikTok i Zomato.

Korzyści z profili podstawowych

Profile podstawowe umożliwiają wstępną kompilację kodu w przypadku krytycznych interakcji użytkowników, takich jak uruchamianie aplikacji, przechodzenie między ekranami czy przewijanie treści. Dzięki temu działają one płynniej od pierwszego uruchomienia. Zwiększając szybkość i responsywność aplikacji, profile podstawowe mogą zwiększyć liczbę aktywnych użytkowników dziennie i średni wskaźnik powrotu.

Profile podstawowe pomagają optymalizować aplikację nie tylko podczas uruchamiania, ale też w przypadku typowych interakcji użytkowników, co poprawia wydajność środowiska wykonawczego aplikacji od pierwszego uruchomienia. Kompilacja AOT z użyciem profilu nie zależy od urządzeń użytkowników i można ją przeprowadzić tylko raz na wersję na komputerze używanym do programowania, a nie na urządzeniu mobilnym. Dzięki udostępnianiu wersji z a profilem podstawowym optymalizacje aplikacji są dostępne znacznie szybciej niż w przypadku korzystania z profili w chmurze tylko.

Jeśli nie używasz profilu podstawowego, cały kod aplikacji jest kompilowany JIT w pamięci po interpretacji lub zapisywany w pliku odex w tle, gdy urządzenie jest bezczynne. Po zainstalowaniu lub zaktualizowaniu aplikacji użytkownicy mają suboptymalne wrażenia od pierwszego uruchomienia do momentu zoptymalizowania nowych ścieżek kodu. Wiele aplikacji po optymalizacji odnotowuje wzrost wydajności o około 30%.

Profile uruchamiania

Profile uruchamiania są podobne do profili podstawowych, ale są używane podczas kompilacji do optymalizacji układu DEX w celu skrócenia czasu uruchamiania, a nie do optymalizacji na urządzeniu. Aby dowiedzieć się więcej o różnicach między profilami uruchamiania a profilami podstawowymi, przeczytaj artykuł Porównanie profili podstawowych i profili uruchamiania. Więcej informacji o optymalizacji układu DEX znajdziesz w artykule Optymalizacje układu DEX i profile uruchamiania.

Rozpocznij

Aby rozpocząć optymalizację wydajności w istniejącej aplikacji, przeczytaj artykuł Tworzenie profili podstawowych.

Generowanie profilu a kompilacje wersji

Ważne jest, aby zrozumieć różnicę w konfiguracjach kompilacji wymaganych podczas generowania plików profili podstawowych i uruchamiania (np. baseline-prof.txt i startup-prof.txt) oraz podczas tworzenia końcowego pliku APK wersji, który korzysta z tych profili.

Podczas generowania plików profili (np. benchmark):

Podczas rejestrowania profilu podstawowego za pomocą testu aplikacja nie może być zaciemniona. Aby wygenerowane reguły profilu dokładnie odpowiadały sygnaturom metod w kodzie, musisz wyłączyć zaciemnianie i optymalizację (R8) w przypadku wariantu kompilacji używanego do generowania profilu. Ten wariant musi różnić się od wariantu kompilacji do publikacji, w którym włączone jest zaciemnianie i optymalizacja. Możesz to zrobić, ustawiając wartość isMinifyEnabled = false dla wariantu kompilacji generowania profilu. Jeśli nie używasz wtyczki Gradle do obsługi profili podstawowych, musisz też upewnić się, że zastosowano opcje -dontobfuscate i -dontoptimize. Wtyczka Gradle do obsługi profili podstawowych automatycznie obsługuje tę konfigurację.

Aby sprawdzić, czy aplikacja nie została zaciemniona podczas generowania profilu, otwórz wygenerowany plik profilu tekstowego (np. baseline-prof.txt) i sprawdź, czy nazwy klas i metod nie są zaciemnione.

Podczas tworzenia końcowego pliku APK wersji:

Podczas tworzenia aplikacji w wersji powinna ona być zaciemniona. Kompilacja wersji musi mieć ustawienie isMinifyEnabled = true, aby korzystać z zaciemniania, minimalizacji i optymalizacji. R8 automatycznie przepisuje reguły z niezaciemnionych plików profilu, aby pasowały do zaciemnionego i zoptymalizowanego kodu w pliku APK wersji. Kompilacja korzysta z niezaciemnionego pliku tekstowego, prawidłowo przekształcając reguły.

Jeśli chcesz, aby optymalizacja układu DEX (oparta na profilach uruchamiania) działała, aplikacja w wersji musi być zaciemniona i używać R8 z włączonymi wszystkimi optymalizacjami.

Zaawansowane przepływy pracy (bez Gradle):

Jeśli do generowania profili używasz zaawansowanego przepływu pracy innego niż Gradle (np. Bazel, Buck lub niestandardowe potoki automatyzacji CI), musisz nadal stosować te same zasady. Podczas rejestrowania profilu aplikacja nie może być zaciemniona ani zoptymalizowana. Podczas tworzenia aplikacji w wersji musisz ją jednak zaciemnić. R8 przetwarza niezaciemniony plik reguł tekstowych i prawidłowo przekształca reguły, aby można je było zastosować do zaciemnionej aplikacji w wersji.

Łańcuch zależności udostępnia stabilne i rozwojowe wersje. Aby wygenerować i zainstalować profil podstawowy, użyj tych obsługiwanych wersji lub nowszych wtyczki Androida do obsługi Gradle, biblioteki Macrobenchmark i instalatora profili. Te zależności są wymagane w różnych momentach i współpracują ze sobą jako łańcuch narzędzi, aby umożliwić optymalny profil podstawowy.

  • Wtyczka Androida do obsługi Gradle: com.android.tools.build:8.0.0
  • Biblioteka Macrobenchmark: androidx.benchmark:benchmark-macro-junit4:1.4.1
  • Instalator profili: androidx.profileinstaller:profileinstaller:1.4.1

Do tworzenia profili podstawowych i zarządzania nimi zalecamy używanie najnowszej wersji wtyczki Androida do obsługi Gradle. Oto główne funkcje dostępne w różnych wersjach wtyczki Androida do obsługi Gradle:

Wersja wtyczki Androida do obsługi Gradle Funkcje
9.1 Pełna obsługa katalogu zestawu źródeł (moduły biblioteki): oprócz katalogów uwzględniających warianty możesz też deklarować wiele plików źródłowych profili podstawowych o dowolnej nazwie, np. src/free/generated/baselineProfiles/baseline-prof1.txt, w przypadku modułów biblioteki i modułów aplikacji.
8.4 Lokalne instalacje aplikacji w przypadku kompilacji, których nie można debugować, za pomocą narzędzia wiersza poleceń Gradle Wrapper lub Androida Studio instalują profile podstawowe, dzięki czemu wydajność lokalnej kompilacji wersji jest bardziej zbliżona do wydajności w środowisku produkcyjnym. Ta aktualizacja nie wpływa na wydajność profili podstawowych w środowisku produkcyjnym.
8.3
  • Częściowa obsługa katalogu zbioru źródeł (moduły biblioteki): deklaruj pliki profili podstawowych uwzględniające warianty, np. src/free/generated/baselineProfiles/baseline-prof.txt, w przypadku modułów biblioteki.
  • Profile podstawowe obejmują klasy desugared.
8.2
  • Przepisywanie reguł przez R8: D8 i R8 mogą przekształcać czytelne dla człowieka reguły profili podstawowych i uruchamiania, aby w pełni uwzględnić wszystkie reguły potrzebne do optymalizacji wydajności aplikacji. Dzięki temu możesz generować profile z niezminimalizowanej kompilacji i stosować je do kompilacji do publikacji. Zwiększa pokrycie metod przez profile podstawowe o około 30% i wydajność aplikacji o około 15%.
  • Profile uruchamiania: generuj ten typ profilu podstawowego, aby informować o układzie kodu w DEX. Zwiększa wydajność uruchamiania o dodatkowe ~15% lub znacznie więcej w przypadku dużych aplikacji.
8.0 Minimalna zalecana wersja: używaj wtyczki Gradle do obsługi profili podstawowych, aby generować profile podstawowe za pomocą jednego zadania Gradle.
  • Pełna obsługa katalogu zestawu źródeł (moduły aplikacji): deklaruj wiele plików źródłowych profili podstawowych i używaj katalogów uwzględniających warianty, np. 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 podstawowy w src/main/baseline-prof.txt pliku.
  • Profile podstawowe są prawidłowo pakowane podczas tworzenia pliku APK z pakietu aplikacji (problem nr 230361284).
  • W przypadku aplikacji z więcej niż 1 .dex plikiem profile podstawowe są prawidłowo pakowane w przypadku głównego .dex pliku.
  • D8 i R8 obsługują generowanie profili uruchamiania z kompilacji, w której isMinifyEnabled jest ustawione na false.

Ustawienia źródła profilu uwzględniające warianty

Używając wtyczki Androida do obsługi Gradle w wersji 8.0 w przypadku aplikacji i w wersji 8.3 w przypadku bibliotek, możesz umieszczać reguły profili podstawowych w specjalnym katalogu zestawu źródeł, co pozwala wyjść poza ograniczenia pojedynczej, stałej ścieżki (np. src/main/baseline-prof.txt) i używać wielu plików.

Ułatwia to solidną obsługę wariantów, umożliwiając definiowanie odrębnych profili podstawowych dostosowanych do konkretnych wersji i typów kompilacji (np. za pomocą katalogów takich jak src/variant/baselineProfiles/), co zapewnia precyzyjne stosowanie reguł optymalizacji wydajności w przypadku każdego unikalnego pliku binarnego aplikacji lub biblioteki.

Przykład generowania profilu

Poniżej znajdziesz przykładową klasę do tworzenia profilu podstawowego na potrzeby uruchamiania aplikacji, a także kilku zdarzeń nawigacji i przewijania za pomocą zalecanej biblioteki Macrobenchmark:

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

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

                // Find and click elements using the new DSL
                onElement { textAsString() == "COMPOSE LAZYLIST" }.click()
                onElement { viewIdResourceName == "myLazyColumn" }.also {
                    it.fling(Direction.DOWN)
                    it.fling(Direction.UP)
                }
                pressBack()
            }
        }
    }
}

Więcej informacji o używaniu biblioteki UI Automator do automatyzacji ścieżek użytkowników znajdziesz w artykule Pisanie testów automatycznych za pomocą UI Automator.

Ten kod w pełnym kontekście i więcej szczegółów znajdziesz w naszych przykładach dotyczących wydajności na GitHubie.

Co uwzględnić?

Gdy używasz profili podstawowych w aplikacji, możesz uwzględnić kod uruchamiania aplikacji i typowe interakcje użytkowników, takie jak nawigacja między ekranami czy przewijanie. Możesz też zbierać całe przepływy, takie jak rejestracja, logowanie czy płatność. Wszystkie ścieżki użytkowników, które uznasz za krytyczne, mogą korzystać z profili podstawowych, ponieważ poprawiają one wydajność środowiska wykonawczego.

Jeśli eksperymentujesz z różnymi metodami zwiększania wydajności, rozważ uwzględnienie profili podstawowych w obu grupach eksperymentu. Dzięki temu możesz ułatwić interpretację wyników, ponieważ wszyscy użytkownicy będą konsekwentnie korzystać ze skompilowanego kodu.

Biblioteki mogą udostępniać własne profile podstawowe i dostarczać je z wersjami, aby zwiększyć wydajność aplikacji. Na przykład przeczytaj sekcję Używanie profilu podstawowego w artykule Wydajność Jetpack Compose.

Jak działają profile podstawowe

Podczas tworzenia aplikacji lub biblioteki rozważ zdefiniowanie profili podstawowych, które obejmują typowe interakcje użytkowników, w przypadku których ważny jest czas renderowania lub opóźnienie. Jak działają:

  1. Dla Twojej aplikacji generowane są czytelne dla człowieka reguły profilu, które są kompilowane do postaci binarnej w aplikacji. Możesz je znaleźć w assets/dexopt/baseline.prof. Następnie możesz przesłać pakiet Android App Bundle (AAB) do Google Play w zwykły sposób.

  2. Google Play przetwarza profil i wysyła go bezpośrednio do użytkowników wraz z plikiem APK. Podczas instalacji środowisko wykonawcze Androida (ART) przeprowadza kompilację AOT metod w profilu, dzięki czemu metody te działają szybciej. Jeśli profil zawiera metody używane podczas uruchamiania aplikacji lub renderowania klatek, użytkownik może zauważyć krótszy czas uruchamiania i mniejsze zacięcia.

  3. Ten przepływ pracy współpracuje z agregacją profili w chmurze, aby dostosować wydajność na podstawie rzeczywistego użycia aplikacji w czasie.

Rysunek 1. Ten diagram przedstawia przepływ pracy profilu podstawowego od przesłania do dostarczenia użytkownikowi końcowemu oraz jego związek z profilami w chmurze.

Porównanie profili podstawowych i profili uruchamiania

Do definiowania i tworzenia plików profili używasz wtyczki Gradle do obsługi profili podstawowych. Ta wtyczka jest powiązana z procesem kompilacji, a wtyczka Androida do obsługi Gradle kompiluje te czytelne dla człowieka reguły profilu do formatu binarnego – spakowanego jako baseline.prof w pliku APK lub AAB – który środowisko wykonawcze Androida może skutecznie wykorzystywać do kompilacji na urządzeniu, pod warunkiem że jest mniejszy niż 1,5 MB.

Utworzone pliki profili mają zwykle nazwy startup-prof.txt i baseline-prof.txt. Chociaż ich zawartość może czasami wyglądać podobnie, zwłaszcza jeśli skupiasz się głównie na uruchamianiu, służą one różnym celom i wpływają na wydajność na różnych etapach:

Profil podstawowy

Plik profilu podstawowego zawiera kompleksowy zestaw reguł, których środowisko wykonawcze Androida (ART) używa do wstępnej kompilacji często używanych ścieżek kodu, co optymalizuje wydajność aplikacji nie tylko podczas uruchamiania.

Plik profilu podstawowego jest zwykle nadzbiorem reguł znajdujących się w profilu uruchamiania. Ten plik zawiera wszystkie reguły wymagane do optymalizacji uruchamiania aplikacji (generowane za pomocą zadania Gradle baselineProfile) oraz dodatkowe profile dla innych krytycznych ścieżek użytkowników. Na przykład przewijanie i przechodzenie między różnymi ekranami.

Te dodatkowe reguły inne niż uruchamianie są generowane niezależnie od wartości pola konfiguracji includeInStartupProfile.

Profil uruchamiania

Plik profilu uruchamiania zawiera reguły zoptymalizowane specjalnie pod kątem ścieżki uruchamiania aplikacji. Podczas kompilacji D8 konwertuje kod bajtowy Java na format DEX. R8 używa następnie tego pliku do wpływania na układ plików DEX, dzięki czemu krytyczny kod uruchamiania jest umieszczany w głównym pliku DEX, co przyspiesza jego wykonywanie. Zwykle należy ustawić wartość includeInStartupProfile na true tylko w przypadku scenariuszy testowych niezbędnych do początkowego wyświetlania aplikacji. Więcej informacji znajdziesz w artykule Tworzenie profili uruchamiania.

Profile w chmurze

Profile w chmurze oferują dodatkową formę optymalizacji z użyciem profilu – agregowaną przez Sklep Google Play i dystrybuowaną na potrzeby kompilacji podczas instalacji – wraz z profilami podstawowymi.

Profile w chmurze są oparte na rzeczywistych interakcjach użytkowników z aplikacją, ale ich dystrybucja trwa kilka godzin lub dni po aktualizacji, co ogranicza ich dostępność. Do czasu pełnego rozpowszechnienia profili wydajność aplikacji jest suboptymalna dla użytkowników nowych lub zaktualizowanych aplikacji. Ponadto profile w chmurze obsługują tylko urządzenia z Androidem 9 (poziom interfejsu API 28) lub nowszym i dobrze skalują się tylko w przypadku aplikacji z wystarczająco dużą bazą użytkowników.

Działanie kompilacji w różnych wersjach Androida

Wersje platformy Androida używają różnych metod kompilacji aplikacji, z których każda ma odpowiedni kompromis w zakresie wydajności. Profile podstawowe ulepszają poprzednie metody kompilacji, ponieważ zapewniają profil dla wszystkich instalacji.

Wersja Androida Metoda kompilacji Metoda optymalizacji
5–6 (poziom interfejsu API 21–23) Pełna kompilacja AOT Cała aplikacja jest optymalizowana podczas instalacji, co powoduje długi czas oczekiwania na możliwość korzystania z aplikacji, zwiększone zużycie pamięci RAM i miejsca na dysku oraz dłuższy czas wczytywania kodu z dysku, co może wydłużyć czas uruchamiania „na zimno”.
7–8.1 (poziom interfejsu API 24–27) Częściowa kompilacja AOT (profil podstawowy) Profile podstawowe są instalowane przez androidx.profileinstaller podczas pierwszego uruchomienia, gdy moduł aplikacji definiuje tę zależność. Środowisko wykonawcze Androida (ART) może to jeszcze bardziej ulepszyć, dodając dodatkowe reguły profilu podczas korzystania z aplikacji i kompilując je, gdy urządzenie jest bezczynne. Optymalizuje to miejsce na dysku i czas wczytywania kodu z dysku, co skraca czas oczekiwania na aplikację.
9 (poziom interfejsu API 28) i nowsze Częściowa kompilacja AOT (profil podstawowy + profil w chmurze) Google Play używa profili podstawowych podczas instalacji aplikacji do optymalizacji pliku APK i profili w chmurze (jeśli są dostępne). Po instalacji profile środowiska wykonawczego Androida (ART) są przesyłane do Google Play, agregowane, a następnie udostępniane innym użytkownikom jako profile w chmurze, gdy instalują lub aktualizują aplikację.

Znane problemy

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

  • 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 Opcje programisty.

  • Aby prawidłowo udostępniać profile podstawowe w bibliotekach, używaj wtyczki Gradle do obsługi profili podstawowych w wersji co najmniej 1.2.3 lub wtyczki Androida do obsługi Gradle w wersji co najmniej 8.3 (problem nr 313992099).

  • Jeśli generujesz profile podstawowe za pomocą polecenia ./gradlew app:generateBaselineProfile, uruchamiają się też testy porównawcze w module testowym, a wyniki są odrzucane. W takim przypadku możesz wygenerować tylko profile podstawowe, uruchamiając polecenie z argumentem -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile. Ten problem został rozwiązany w wtyczce Androida do obsługi Gradle w wersji 8.2.

  • Polecenie generowania profili podstawowych dla wszystkich rodzajów kompilacji – ./gradlew app:generateBaselineProfile – generuje profile podstawowe tylko dla rodzaju kompilacji do publikacji. Ten problem został rozwiązany w wtyczce Androida do obsługi Gradle w wersji 8.1.

  • Kanały dystrybucji aplikacji inne niż Sklep Google Play mogą nie obsługiwać używania profili podstawowych podczas instalacji. Użytkownicy aplikacji zainstalowanych za pomocą tych kanałów nie widzą korzyści, dopóki nie zostanie uruchomiona optymalizacja DEX w tle, co zwykle następuje w nocy.

  • Wewnętrzne udostępnianie aplikacji w Sklepie Play nie obsługuje profili podstawowych, ale obsługuje je ścieżka testów wewnętrznych.

  • Optymalizacje baterii na niektórych urządzeniach, np. Huawei, mogą zakłócać instalację profilu. Aby zapewnić skuteczną instalację profili, wyłącz optymalizacje baterii na urządzeniach testowych.

Dodatkowe materiały

Polecane dla Ciebie