Porównanie danych tworzenia i wyświetlania

Jetpack Compose przyspiesza tworzenie interfejsu użytkownika i ulepsza tworzenie aplikacji na Androida. Pamiętaj jednak, że dodanie Compose do istniejącej aplikacji może wpływać na dane takie jak rozmiar pliku APK, kompilacja i wydajność w czasie działania.

Rozmiar pliku APK i czas kompilacji

W tej sekcji omawiamy wpływ na rozmiar pliku APK i czas kompilacji na przykładzie aplikacji Sunflower, która demonstruje sprawdzone metody migracji aplikacji opartej na widoku do Compose.

Rozmiar pliku APK

Dodawanie bibliotek do projektu zwiększa rozmiar pliku APK. Podane niżej wyniki dotyczą zoptymalizowanych wersji APK każdego projektu z włączonym kompresowaniem zasobów i kodu, korzystających z pełnego trybu R8 i zmierzonych za pomocą APK Analyzer.

Tylko wyświetlenia Widok mieszany i tworzenie wiadomości Tylko tworzenie
Rozmiar do pobrania 2252 KB 3034 KB 2966 KB

Po pierwszym dodaniu Compose do Sunflower rozmiar pliku APK zwiększył się z 2252 KB do 3034 KB, czyli o 782 KB. Wygenerowany APK zawierał wersję interfejsu użytkownika z mieszanką widoków i Compose. Należy się spodziewać wzrostu liczby zależności, ponieważ do Sunflower dodano dodatkowe zależności.

Z kolei po migracji aplikacji Sunflower do aplikacji tylko z Compose rozmiar pliku APK zmniejszył się z 3034 KB do 2966 KB, czyli o 68 KB. Ten spadek był spowodowany usunięciem nieużywanych zależności widoku, takich jak AppCompatConstraintLayout.

Czas kompilacji

Dodanie Compose wydłuża czas kompilacji aplikacji, ponieważ kompilator Compose przetwarza komponenty w aplikacji. Wyniki te zostały uzyskane za pomocą samodzielnego narzędzia gradle-profiler, które wykonuje kompilację kilka razy, aby można było uzyskać średni czas kompilacji wersji debugowej aplikacji Sunflower:

gradle-profiler --benchmark --project-dir . :app:assembleDebug
Tylko wyświetlenia Widok mieszany i tworzenie wiadomości Tylko tworzenie
Średni czas kompilacji 299,47 ms 399,09 ms 342,16 ms

Po pierwszym dodaniu funkcji Utwórz do Sunflower średni czas kompilacji wzrósł z 299 do 399 ms, czyli wzrost o 100 ms. Ten czas wynika z tego, że kompilator Compose wykonuje dodatkowe zadania, aby przekształcić kod Compose zdefiniowany w projekcie.

Natomiast po zakończeniu migracji projektu Sunflower do Compose średni czas kompilacji skrócił się do 342 ms (o 57 ms mniej). Zmniejszenie to można przypisać kilku czynnikom, które łącznie skracają czas kompilacji, takim jak usunięcie wiązania danych, przeniesienie zależności używających kapt do KSP i zaktualizowanie kilku zależności do ich najnowszych wersji.

Podsumowanie

Zastosowanie Compose spowoduje zwiększenie rozmiaru pliku APK aplikacji oraz wydłużenie czasu kompilacji z powodu procesu kompilacji kodu Compose. Jednak te kompromisy należy porównać z korzyściami wynikającymi z użycia Compose, zwłaszcza w zakresie zwiększenia produktywności programistów po wdrożeniu Compose. Na przykład zespół Sklepu Play odkrył, że tworzenie interfejsu wymaga znacznie mniej kodu, czasami nawet do 50%, co zwiększa produktywność i możliwość utrzymania kodu.

Więcej studiów przypadków znajdziesz w artykule Wdrażanie Compose w usłudze Teams.

Wydajność w środowisku wykonawczym

Z tej sekcji dowiesz się, jak porównać wydajność Jetpack Compose z wydajnością systemu View i jak ją mierzyć.

Inteligentne zmiany składu

Jeśli niektóre części interfejsu są nieprawidłowe, Compose próbuje ponownie skompilować tylko te części, które wymagają aktualizacji. Więcej informacji znajdziesz w dokumentacji dotyczącej cyklu życia kompozytówetapów Jetpack Compose.

Profile podstawowe

Profile punktowe to doskonały sposób na przyspieszenie typowych ścieżek użytkownika. Uwzględnienie w aplikacji profilu referencyjnego może zwiększyć szybkość wykonywania kodu o około 30% w porównaniu z pierwszym uruchomieniem, ponieważ pozwala uniknąć interpretacji i etapów kompilacji just-in-time (JIT) dla uwzględnionych ścieżek kodu.

Biblioteka Jetpack Compose zawiera własny profil Baseline i te optymalizacje są automatycznie dostępne, gdy używasz w aplikacji Compose. Te optymalizacje mają jednak wpływ tylko na ścieżki kodu w bibliotece Compose, dlatego zalecamy dodanie profilu Baseline do aplikacji, aby obsługiwać ścieżki kodu poza funkcją Compose.

Porównanie z systemem View

Jetpack Compose oferuje wiele ulepszeń w porównaniu z systemem View. Te ulepszenia opisujemy w kolejnych sekcjach.

Wszystko rozszerza widok

Każdy element View, który jest wyświetlany na ekranie, np. TextView, Button lub ImageView, wymaga przydzielenia pamięci, jawnego śledzenia stanu i różnych wywołań zwrotnych, aby obsługiwać wszystkie przypadki użycia. Ponadto właściciel niestandardowego elementu View musi zastosować jawną logikę, aby zapobiec ponownemu rysowaniu, gdy nie jest to konieczne, np. w przypadku powtarzającego się przetwarzania danych.

Jetpack Compose rozwiązuje ten problem na kilka sposobów. Funkcja tworzenia nie zawiera jawnych obiektów aktualizowanych w widokach rysunków. Elementy interfejsu to proste funkcje, które można łączyć. Informacje o nich są zapisywane w składance w sposób umożliwiający jej odtworzenie. Dzięki temu można ograniczyć śledzenie stanu, alokację pamięci i wywołania zwrotne tylko do tych komponentów, które wymagają tych funkcji, zamiast wymagać ich od wszystkich rozszerzeń danego typu View.

Ponadto Compose udostępnia inteligentne rekompozycje, które odtwarzają wcześniej uzyskany wynik, jeśli nie musisz wprowadzać zmian.

Wiele przejść przez układ

Tradycyjne grupy widoków mają wiele możliwości w swoich miarach i interfejsach API układu, co powoduje, że są one podatne na wielokrotne przejścia układu. Te wielokrotne wejścia układu mogą powodować działanie wykładnicze, jeśli są wykonywane w określonych zagnieżdżonych punktach w hierarchii widoku.

Jetpack Compose wymusza stosowanie karnetu pojedynczego układu dla wszystkich elementów kompozycyjnych układu za pomocą umowy dotyczącej interfejsu API. Dzięki temu funkcja Compose może sprawnie obsługiwać głębokie drzewa UI. Jeśli potrzebne są liczne pomiary, Compose zawiera własne pomiary.

Wyświetlanie wydajności uruchamiania

System widoku musi napompować układy XML podczas wyświetlania określonego układu po raz pierwszy. W Jetpack Compose można zaoszczędzić na kosztach, ponieważ układy są pisane w języku Kotlin i skompilowane tak samo jak reszta aplikacji.

Benchmark Compose

W Jetpack Compose 1.0 występują znaczne różnice w wydajności aplikacji w trybach debugrelease. Aby uzyskać wiarygodne dane o czasie, zawsze używaj wersji release zamiast wersji debug podczas profilowania aplikacji.

Aby sprawdzić wydajność kodu Jetpack Compose, możesz użyć biblioteki Jetpack Macrobenchmark. Informacje o tym, jak używać go w Jetpack Compose, znajdziesz w projekcie MacrobenchmarkSample.

Zespół Jetpack Compose używa też Macrobenchmark do wykrywania wszelkich regresji, które mogą wystąpić. Aby śledzić regresje, możesz na przykład skorzystać z benchmarku kolumny leniwej i odpowiedniej tablicy.

Instalacja profilu kompozytowego

Jetpack Compose jest biblioteką niespakowaną, więc nie korzysta z Zygote, który wczytuje wstępnie klasy i elementy rysowalne z UI Toolkit systemu View. Jetpack Compose 1.0 korzysta z instalacji profilu w przypadku wersji release. Profile instalatora umożliwiają aplikacjom określenie kodu krytycznego, który ma zostać skompilowany w czasie instalacji w trybie AOT (z wyprzedzeniem). Compose udostępnia reguły instalacji profilu, które skracają czas uruchamiania i zmniejszają zacięcia w aplikacjach Compose.