Korzystanie z Analizatora konfiguracji R8

Analizator konfiguracji R8 to narzędzie, które pomaga maksymalnie wykorzystać zalety R8, dostarczając szczegółowych informacji o jakości konfiguracji aplikacji. Umożliwia śledzenie i ulepszanie optymalizacji R8 przez monitorowanie kluczowych danych, a mianowicie wyników kompresji, optymalizacji i zaciemniania, które wskazują odsetek kodu dostępnego do optymalizacji. Analizator pomaga Ci dopracować konfigurację, aby R8 mógł skutecznie optymalizować jak najwięcej klas, pól i metod. W tym celu analizator identyfikuje ogólne lub niepotrzebne reguły zachowywania, w tym te wprowadzone przez biblioteki innych firm.

Generowanie raportu

W przypadku AGP w wersji 9.3.0-alpha05 i nowszych raport jest generowany automatycznie w build/outputs/mapping/release/configanalyzer.html podczas kompilacji R8. Aby wyłączyć automatyczne generowanie danych wyjściowych, ustaw tę właściwość Gradle:

android.experimental.r8.enableR8ConfigurationAnalyzer=false

W przypadku wtyczki Androida do obsługi Gradle w wersji 9.2 i starszych ustaw właściwość systemową com.android.tools.r8.dumpkeepradiushtmltodirectory podczas uruchamiania zadania Gradle z kompilacją włączoną za pomocą R8.

./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=<output_directory>

Aby na przykład wygenerować raport HTML w katalogu /tmp/r8analysis, użyj tego polecenia:

// To create the /tmp/r8analysis folder.
mkdir -p /tmp/r8analysis

// To generate the report in the /tmp/r8analysis folder.
./gradlew assembleRelease \
    -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=/tmp/r8analysis

Interpretowanie raportu

Analizator konfiguracji R8 dostarcza informacji o konfiguracji R8 aplikacji i wpływie każdej reguły zachowywania na aplikację. Pomaga to uzyskać maksymalną optymalizację R8 i zwiększyć wydajność aplikacji. Skorzystaj z tych wyników, aby dowiedzieć się, jaka część Twojej bazy kodu jest dostępna do optymalizacji przez R8.

Przykład sekcji podsumowania raportu
Rysunek 1. Przykład sekcji podsumowania raportu

Malejący wynik

Gdy R8 zmniejsza rozmiar aplikacji, identyfikuje i usuwa nieużywany kod oraz zasoby, co pozwala zmniejszyć ogólny rozmiar aplikacji i zapewnić, że ostateczna kompilacja będzie jak najmniejsza. Zmniejszający się wynik śledzi odsetek klas, pól i metod, które podlegają zmniejszaniu. Na przykład wynik 66% oznacza, że R8 może przeprowadzić zmniejszanie w 66% kodu.

Wynik optymalizacji

R8 przeprowadza optymalizacje, takie jak wstawianie metod i scalanie klas, co poprawia uruchamianie i pamięć aplikacji. Wynik optymalizacji śledzi odsetek klas, pól i metod, które podlegają optymalizacjom R8. Jeśli na przykład wynik optymalizacji wynosi 66%, oznacza to, że R8 może przeprowadzić optymalizację tylko w 66% kodu.

Ocena zaciemnienia

Zaciemniając klasy, pola i metody, R8 skraca nazwy i zmniejsza rozmiar metadanych aplikacji, co pozwala oszczędzać pamięć. Wynik zaciemniania określa odsetek kodu dostępnego do zaciemniania w bazie kodu.

Uściślanie reguł przechowywania

Aby poprawić wyniki i odblokować lepszą optymalizację R8, musisz dopracować reguły zachowywania, aby niepotrzebnie nie uniemożliwiały R8 optymalizacji aplikacji. Zachowuj tylko klasy, metody lub pola, do których uzyskuje się dostęp za pomocą refleksji.

Aby to zrobić, użyj analizy reguł zachowywania.

Przykład analizy reguły zachowywania
Rysunek 2. Przykład analizy reguły zachowywania.

Aby zobaczyć szczegółową analizę reguły, kliknij ją, aby otworzyć ekran szczegółów.

Przykład analizy reguły zachowywania
Rysunek 3. Przykład analizy reguły zachowywania.

Jak doprecyzować reguły przechowywania

Aby dopracować reguły zachowywania i w pełni wykorzystać możliwości optymalizacji R8 w przypadku aplikacji:

  1. W analizatorze konfiguracji możesz sprawdzić, jaki odsetek klas, pól i metod nie może zostać zoptymalizowany przez R8 w przypadku każdej reguły zachowywania. Użyj tej opcji, aby zidentyfikować reguły zachowywania, które uniemożliwiają optymalizację w dużej liczbie klas, pól lub metod. Wymienione są też właściwości optymalizacji, które są blokowane przez poszczególne reguły zachowywania.
  2. Jeśli widzisz regułę zachowywania, która uniemożliwia optymalizację dużej liczby klas, sprawdź, które klasy, pola i metody są chronione przed optymalizacją przez tę regułę. Zobacz, czy reguła zachowywania nie chroni elementów, które nie są wywoływane dynamicznie za pomocą refleksji.
  3. Ogranicz blokowanie optymalizacji przez reguły zachowywania, kierując reklamy tylko na niezbędne klasy, pola lub metody, wybierając odpowiednią opcję zachowywaniastosując sprawdzone metody.
  4. Sprawdź i przeprowadź testy, które obejmują klasy, pola i metody, których dotyczy reguła zachowywania, a następnie dopracuj reguły zachowywania.

Sprawdzanie optymalizacji bibliotek

Gdy integrujesz biblioteki zewnętrzne, często zawierają one własne reguły przechowywania dla konsumentów, które współpracują z R8. Autor biblioteki nie może przewidzieć Twojej konkretnej implementacji, dlatego czasami pisze zachowawcze, szeroko zakrojone reguły, które uniemożliwiają optymalizację w większej liczbie klas, pól i metod niż jest to konieczne. Może to uniemożliwić R8 optymalizację części aplikacji, które nie mają nic wspólnego z rzeczywistym działaniem biblioteki. Możesz użyć narzędzia R8 Configuration Analyzer, aby zidentyfikować biblioteki wprowadzające reguły, które negatywnie wpływają na optymalizację aplikacji.

Użyj analizatora konfiguracji, aby sprawdzić łączny efekt wszystkich scalonych reguł przechowywania danych konsumenckich. Analizując wpływ każdej reguły zachowywania pochodzącej z biblioteki innej firmy, możesz identyfikować i śledzić konkretne biblioteki innych firm, które uniemożliwiają przeprowadzenie w aplikacji dużej liczby optymalizacji.

Optymalizacja bibliotek

  • Jeśli biblioteka zawiera zbyt ogólną regułę, zalecamy skontaktowanie się z osobą zarządzającą biblioteką i przesłanie jej danych z raportu, aby pokazać, jak obecne reguły wpływają na wyniki optymalizacji aplikacji. Jeśli jest to biblioteka zewnętrzna, przed zgłoszeniem problemu sprawdź, czy nie ma w niej już zgłoszonych błędów.
  • W razie potrzeby możesz przetestować potencjalne ulepszenia, filtrując reguły z określonej biblioteki. Możesz zaimportować reguły biblioteki do projektu, wykluczyć ogólne reguły i ponownie uruchomić analizator konfiguracji, aby zmierzyć potencjalne korzyści w zakresie rozmiaru i wydajności.

Reguły podrzędne

Może się zdarzyć, że kilka reguł zachowywania będzie się nakładać, a jedna z nich może uniemożliwiać optymalizację w większym stopniu niż jest to konieczne. Jeśli w bazie kodu znajdują się 2 reguły zachowywania.

# Prevents optimization in the entire package
# Remove this to improve optimization
-keep class com.example.package.** { *; }

# Prevents optimization to the class inside the package
-keep class com.example.package.Myclass

Pierwsza reguła zachowywania, która zapobiega optymalizacji całego pakietu, obejmuje drugą regułę zachowywania, która jest kierowana na klasę w pakiecie zachowanym przez pierwszą regułę zachowywania. Gdy reguły zachowywania się pokrywają, jedna z nich może blokować więcej optymalizacji niż jest to konieczne. Dzięki dopracowaniu tych pokrywających się reguł możesz zmaksymalizować optymalizację R8 i wyeliminować dług techniczny. Ten proces polega na uproszczeniu konfiguracji, aby zachować tylko niezbędny kod, a jednocześnie w pełni wykorzystać możliwości optymalizacji R8.

Przykład sekcji podsumowania raportu
Rysunek 4. Przykład reguł wchłoniętych w raporcie

Optymalizacja reguł podrzędnych

  1. Znajdź reguły zachowywania, które są zastępowane przez inne reguły, za pomocą narzędzia R8 Configuration Analyzer.
  2. Określ dokładne klasy, pola lub metody w bazie kodu, które faktycznie korzystają z odbicia i muszą być zachowane za pomocą reguł keep. Ta wiedza pomoże Ci dopracować reguły przechowywania.
  3. Za pomocą analizatora konfiguracji porównaj wpływ poszczególnych reguł kierowanych na te same klasy, pola lub metody. Możesz użyć odsetka optymalizacji zapobiegniętej przez każdą regułę zachowywania, aby określić, która z nich jest szersza, a która węższa.
    1. Jeśli wąska reguła jest napisana precyzyjnie (zachowuje tylko dokładnych członków lub klasy, do których uzyskuje się dostęp przez odbicie), usuń szerszą regułę zachowywania. Bezpiecznie odblokowuje to optymalizacje R8 w pozostałej części pakietu.
    2. Jeśli reguła ogólna jest kierowana na odpowiednie klasy, zachowaj ją i usuń regułę szczegółową. Cienka linia jest po prostu zbędnym elementem. Upewnij się, że reguła ogólna została doprecyzowana tak, aby obejmowała tylko zidentyfikowane przez Ciebie klasy, pola lub metody.

Sprawdź i przetestuj zmiany: ponownie uruchom analizator konfiguracji, aby upewnić się, że konflikt został rozwiązany. Następnie skompiluj kompilację do publikacji i przetestuj zmiany, aby upewnić się, że baza kodu działa zgodnie z oczekiwaniami.

Usuwanie niepotrzebnych reguł

Za pomocą analizatora konfiguracji możesz systematycznie sprawdzać bazę kodu, aby identyfikować i usuwać przestarzałe reguły zachowywania, które zaśmiecają konfigurację. Analizator konfiguracji R8 wyróżnia 2 główne źródła zbędnych reguł:

  • Nieużywane reguły: reguły, które nie pasują do żadnych klas, metod ani pól w bieżącej kompilacji. Często pozostają one po refaktoryzacji kodu, usunięciu zależności lub skopiowaniu i wklejeniu konfiguracji, które nie są już istotne, co niepotrzebnie komplikuje konfigurację.
  • Identyczne reguły: identyczne reguły zachowywania to reguły, które są kierowane na te same klasy, pola i metody lub zduplikowane deklaracje reguły zachowywania w tym samym lub w różnych plikach reguł zachowywania.

Oba typy reguł powodują bałagan w konfiguracji, co utrudnia jej utrzymanie i debugowanie. Dzięki temu możesz uporządkować konfigurację.