Omówienie profili podstawowych

Profile podstawowe zwiększają szybkość wykonywania kodu o około 30% od pierwszego uruchomienia, ponieważ unikają interpretacji i kompilacji just-in-time (JIT) w przypadku uwzględnionych ścieżek kodu.

Dzięki dostarczaniu profilu podstawowego w aplikacji lub bibliotece środowisko wykonawcze Androida (ART) może optymalizować określone ścieżki kodu za pomocą kompilacji AOT (Ahead-of-Time), co zwiększa wydajność każdego nowego użytkownika i każdej aktualizacji aplikacji. Optymalizacja na podstawie profilu (PGO) umożliwia aplikacjom optymalizację uruchamiania, zmniejszenie zacięć interakcji i poprawę ogólnej wydajności działania 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 dane biznesowe, znajdziesz w historiach Josh, Lyft, TikTokaZomato.

Korzyści z profili podstawowych

Profile bazowe umożliwiają wstępną kompilację kodu w przypadku kluczowych interakcji użytkownika, takich jak uruchamianie aplikacji, przechodzenie między ekranami czy przewijanie treści, dzięki czemu działają one płynniej od pierwszego uruchomienia. Zwiększając szybkość i czas reakcji aplikacji, profile bazowe mogą przyczynić się do zwiększenia liczby aktywnych użytkowników dziennie i wyższego średniego wskaźnika ponownych wizyt.

Profile podstawowe pomagają w optymalizacji wykraczającej poza uruchamianie aplikacji, ponieważ zawierają typowe interakcje użytkowników, które poprawiają działanie aplikacji od pierwszego uruchomienia. Kompilacja AOT z przewodnikiem nie zależy od urządzeń użytkowników i może być przeprowadzana raz na wersję na komputerze używanym do programowania zamiast na urządzeniu mobilnym. Dzięki dostarczaniu wersji z  profilem podstawowym optymalizacje aplikacji stają się dostępne znacznie szybciej niż w przypadku korzystania tylko z profili w chmurze.

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

Profile uruchamiania

Profile uruchamiania są podobne do profili podstawowych, ale są używane w czasie kompilacji do optymalizacji układu DEX pod kątem szybszego uruchamiania, a nie do optymalizacji na urządzeniu. Więcej informacji o różnicach między profilami startowymi a profilami podstawowymi znajdziesz w artykule Porównanie profili podstawowych i startowych. 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, zapoznaj się z artykułem Tworzenie profili podstawowych.

Generowanie profili a wersje

Ważne jest, aby znać różnice w konfiguracjach kompilacji wymaganych podczas generowania plików profilu podstawowego i profilu uruchamiania (np. baseline-prof.txtstartup-prof.txt) w porównaniu z kompilowaniem końcowego pakietu APK wersji, który korzysta z tych profili.

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

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

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

Podczas tworzenia końcowej wersji pliku APK:

Podczas tworzenia aplikacji w wersji do publikacji powinna ona być zaciemniona. Aby korzystać z zaciemniania kodu, minimalizacji i optymalizacji, wersja aplikacji musi mieć isMinifyEnabled = true. 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 działała optymalizacja układu DEX (oparta na profilach uruchamiania), aplikacja w wersji do publikacji musi być zaciemniona i musi używać R8 z włączoną optymalizacją.

Zaawansowane przepływy pracy (bez Gradle):

Jeśli do generowania profili używasz zaawansowanego przepływu pracy innego niż Gradle (np. Bazel, Buck lub niestandardowych potoków automatyzacji CI), musisz postępować zgodnie z tymi samymi zasadami. Podczas rejestrowania profilu aplikacja nie może być zaciemniona ani zoptymalizowana. Gdy jednak tworzysz aplikację w wersji do wdrożenia, musisz ją zaciemnić. R8 przetwarza niezaszyfrowany plik reguł tekstowych i prawidłowo przekształca reguły, aby można było je zastosować do zaszyfrowanej wersji aplikacji.

Łańcuch zależności udostępnia stabilne i rozwojowe wersje. Aby wygenerować i zainstalować profil podstawowy, użyj tych wersji wtyczki Androida do obsługi Gradle, biblioteki Macrobenchmark i instalatora profili lub nowszych. 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 testów porównawczych makro:androidx.benchmark:benchmark-macro-junit4:1.5.0
  • Instalator profilu: androidx.profileinstaller:profileinstaller:1.4.1

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

Wersja AGP Funkcje
9.1 Pełna obsługa katalogów zestawów źródeł (moduły biblioteki): oprócz katalogów uwzględniających warianty możesz deklarować wiele plików źródłowych profilu podstawowego 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 z możliwością debugowania za pomocą narzędzia wiersza poleceń Gradle Wrapper lub Androida Studio instalują profile podstawowe, dzięki czemu wydajność lokalnej kompilacji do publikacji jest bardziej zbliżona do wydajności wersji produkcyjnej. Ta aktualizacja nie wpływa na wydajność profili podstawowych w środowisku produkcyjnym.
8.3
  • Obsługa katalogu częściowego zbioru źródeł (moduły biblioteki): deklarowanie plików profilu podstawowego uwzględniających warianty, np.src/free/generated/baselineProfiles/baseline-prof.txt, w przypadku modułów biblioteki.
  • Profile podstawowe zawierają odcukrzone klasy.
8.2
  • Przepisywanie reguł przez R8: D8 i R8 mogą przekształcać czytelne dla człowieka reguły profilu podstawowego i profilu uruchamiania, aby w pełni uwzględniać wszystkie reguły potrzebne do optymalizacji wydajności aplikacji. Dzięki temu możesz generować profile z niezminifikowanej kompilacji i stosować je do zminifikowanej kompilacji do publikacji. Zwiększa pokrycie profili podstawowych metod o około 30% i wydajność aplikacji o około 15%.
  • Uruchamianie profili: 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.
z Androidem 8.0 Minimalna zalecana wersja: użyj wtyczki Gradle Baseline Profile, aby wygenerować profile podstawowe za pomocą jednego zadania Gradle.
  • Pełna obsługa katalogu zestawu źródeł (moduły aplikacji): deklarowanie wielu plików źródłowych profilu podstawowego i używanie 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 pliku src/main/baseline-prof.txt.
  • Profile podstawowe są prawidłowo spakowane podczas tworzenia pliku APK z pakietu aplikacji (problem #230361284).
  • W przypadku aplikacji z więcej niż 1 .dex plikiem profile podstawowe są prawidłowo spakowane dla głównego .dex pliku.
  • D8 i R8 obsługują generowanie profili uruchamiania z kompilacji, w której isMinifyEnabled jest ustawiona na false.

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

Korzystając z wtyczki Androida do obsługi Gradle (AGP) w wersji 8.0 w przypadku aplikacji i wtyczki AGP w wersji 8.3 w przypadku bibliotek, możesz umieszczać reguły profilu podstawowego w dedykowanym katalogu zbioru źródeł, co pozwala wyjść poza ograniczenia pojedynczej, stałej ścieżki (np. src/main/baseline-prof.txt) i umożliwia korzystanie z wielu plików.

Ułatwia to obsługę różnych wariantów, umożliwiając zdefiniowanie odrębnych profili bazowych dostosowanych do konkretnych wersji i typów kompilacji (np. za pomocą katalogów takich jak src/variant/baselineProfiles/). Dzięki temu reguły optymalizacji wydajności są precyzyjnie stosowane do 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 z użyciem 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żytkownika znajdziesz w artykule Pisanie testów automatycznych za pomocą UI Automator.

Ten kod w pełnym kontekście i bardziej szczegółowo znajdziesz w naszych przykładach wydajności na GitHubie.

Co uwzględnić?

Korzystając w aplikacji z profili podstawowych, możesz uwzględnić kod uruchamiania aplikacji i typowe interakcje użytkownika, takie jak nawigacja między ekranami czy przewijanie. Możesz też zbierać całe ścieżki, takie jak rejestracja, logowanie czy płatność. Profile podstawowe mogą poprawić wydajność w czasie działania wszystkich ścieżek użytkownika, które uznasz za kluczowe.

Jeśli eksperymentujesz z różnymi metodami poprawy 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 uruchamiać skompilowany kod.

Biblioteki mogą udostępniać własne profile podstawowe i dostarczać je z wersjami, aby poprawić wydajność aplikacji. Więcej informacji znajdziesz na przykład w sekcji Używanie profilu podstawowego w artykule o wydajności Jetpack Compose.

Jak działają profile podstawowe

Podczas tworzenia aplikacji lub biblioteki warto zdefiniować profile podstawowe, aby obejmowały 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 reguły profilu, które są kompilowane do postaci binarnej w aplikacji. Znajdziesz je w assets/dexopt/baseline.prof. Następnie możesz przesłać pakiet aplikacji na Androida (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 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 zacinanie się.

  3. Ten proces współpracuje z agregacją profili w chmurze, aby dostosowywać wydajność na podstawie rzeczywistego korzystania z aplikacji w czasie.

Rysunek 1. Ten diagram przedstawia przepływ pracy profilu podstawowego od przesyłania do dostarczania 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 profilu podstawowego używasz wtyczki Gradle Baseline Profile. Ta wtyczka jest powiązana z procesem kompilacji, a AGP kompiluje te czytelne dla człowieka reguły profilu do formatu binarnego, który jest pakowany jako baseline.prof w pliku APK lub AAB.ART może go skutecznie używać do kompilacji na urządzeniu, pod warunkiem że rozmiar pliku jest mniejszy niż 1,5 MB.

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

profil podstawowy

Plik profilu podstawowego zawiera obszerny zestaw reguł, których środowisko wykonawcze Androida (ART) używa do wstępnego kompilowania 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 startowym. Ten plik zawiera wszystkie reguły wymagane do optymalizacji uruchamiania aplikacji (wygenerowane za pomocą zadania Gradle baselineProfile) oraz dodatkowe profile innych ważnych ścieżek użytkownika. Na przykład przewijanie i przechodzenie między różnymi ekranami.

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

Profil startupu

Plik profilu uruchamiania zawiera reguły zoptymalizowane pod kątem ścieżki uruchamiania aplikacji. Podczas kompilacji D8 konwertuje kod bajtowy Javy na format DEX. R8 używa tego pliku, aby wpływać na układ plików DEX, dbając o to, aby krytyczny kod uruchamiania był umieszczany w głównym pliku DEX w celu szybszego wykonania. Wartość includeInStartupProfile należy ustawiać na true tylko w przypadku scenariuszy testowych niezbędnych do początkowego wyświetlania aplikacji. Więcej informacji znajdziesz w artykule Tworzenie profili startupów.

Profile w chmurze

Profile Cloud to dodatkowa forma optymalizacji PGO – agregowana przez Sklep Google Play i dystrybuowana na potrzeby kompilacji w czasie instalacji – wraz z profilami podstawowymi.

Profile w chmurze są tworzone na podstawie interakcji użytkowników z aplikacją w rzeczywistym świecie, ale ich rozpowszechnianie po aktualizacji trwa od kilku godzin do kilku dni, co ogranicza ich dostępność. Dopóki profile nie zostaną w pełni rozpowszechnione, wydajność aplikacji będzie optymalna dla użytkowników nowych lub zaktualizowanych aplikacji. Profile w chmurze obsługują tylko urządzenia z Androidem 9 (poziom interfejsu API 28) lub nowszym i skalują się dobrze tylko w przypadku aplikacji z odpowiednio dużą bazą użytkowników.

Zachowanie kompilacji w różnych wersjach Androida

Wersje platformy Android wykorzystują różne metody kompilacji aplikacji, z którymi wiążą się różne kompromisy dotyczące wydajności. Profile podstawowe są lepsze od poprzednich metod kompilacji, ponieważ zapewniają profil dla wszystkich instalacji.

Wersja Androida Metoda kompilacji Podejście do optymalizacji
5–6 (poziom API 21–23) Pełne AOT Cała aplikacja jest optymalizowana podczas instalacji, co powoduje długi czas oczekiwania na możliwość korzystania z niej, zwiększone zużycie pamięci RAM i miejsca na dysku oraz dłuższy czas ładowania 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 przy pierwszym uruchomieniu, gdy moduł aplikacji definiuje tę zależność. ART może jeszcze bardziej poprawić wydajność, dodając dodatkowe reguły profilu podczas korzystania z aplikacji i kompilując je, gdy urządzenie jest nieaktywne. Optymalizuje to miejsce na dysku i czas wczytywania kodu z dysku, co skraca czas oczekiwania na aplikację.
9 (poziom 28 interfejsu API) i nowsze Częściowa kompilacja AOT (profil podstawowy + profil w chmurze) Podczas instalacji aplikacji Google Play używa profili podstawowych, aby zoptymalizować plik APK i profile w chmurze (jeśli są dostępne). Po zainstalowaniu profile 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 powieść 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ńOpcjach programisty.

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

  • Jeśli wygenerujesz profile bazowe za pomocą polecenia ./gradlew app:generateBaselineProfile, zostaną też uruchomione testy porównawcze w module testowym, a wyniki zostaną odrzucone. W takim przypadku możesz wygenerować tylko profile podstawowe, uruchamiając polecenie z parametrem -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile. Ten problem został rozwiązany w AGP 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 zobaczą korzyści, dopóki nie zostanie uruchomiona optymalizacja dex w tle, co prawdopodobnie nastąpi w nocy.

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

  • Optymalizacja baterii na niektórych urządzeniach, np. Huawei, może utrudniać instalację profilu. Aby zapewnić prawidłową instalację profili, wyłącz optymalizację baterii na urządzeniach testowych.

Dodatkowe materiały

Polecane dla Ciebie