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 plików APK wersji każdego projektu z włączonym kompresowaniem zasobów i kodu w trybie pełnym R8 i zmierzone za pomocą APK Analyzer.

Tylko wyświetlenia Złożone widoki 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ł interfejs użytkownika z użyciem widoków i Compose. Należy się spodziewać wzrostu liczby zależności, ponieważ do Sunflower dodano dodatkowe zależności.

Natomiast po przeniesieniu aplikacji Sunflower do 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. Poniższe wyniki 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 debugowania aplikacji Sunflower:

gradle-profiler --benchmark --project-dir . :app:assembleDebug
Tylko wyświetlenia Złożone widoki i tworzenie wiadomości Tylko tworzenie
Średni czas kompilacji 299,47 ms 399,09 ms 342,16 ms

Gdy po raz pierwszy dodaliśmy Compose do Sunflower, średni czas kompilacji wzrósł z 299 ms do 399 ms, czyli o 100 ms. Ten czas wynika z tego, że kompilator Compose wykonuje dodatkowe zadania, aby przekształcić kod Compose zdefiniowany w projekcie.

Z kolei średni czas kompilacji skrócił się do 342 ms (o 57 ms krócej), gdy zakończyliśmy migrację Sunflower do Compose. 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. Należy jednak porównać te kompromisy z zaletami 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

Gdy 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 Cykl życia kompozytowychEtapy Jetpack Compose.

Profile podstawowe

Profile punktowe to doskonały sposób na przyspieszenie typowych ścieżek użytkownika. Dodanie do 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 kompilacji na żądanie (JIT) ścieżek kodu.

Biblioteka Jetpack Compose zawiera własny profil podstawowy. Te optymalizacje są automatycznie stosowane, gdy używasz Compose w aplikacji. Jednak te optymalizacje mają wpływ tylko na ścieżki kodu w bibliotece Compose, dlatego zalecamy dodanie profilu podstawowego do aplikacji, aby objąć ścieżki kodu spoza Compose.

Porównanie z systemem View

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

Wszystko rozszerza widok

Każdy element View, który jest wyświetlany na ekranie, np. TextView, Button lub ImageView, wymaga alokacji 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. W Compose nie ma wyraźnych obiektów do aktualizowania w przypadku widoków rysunku. Elementy interfejsu to proste funkcje, które można łączyć. Informacje o nich są zapisywane w kompozycji w sposób umożliwiający ich ponowne odtworzenie. Dzięki temu można ograniczyć śledzenie stanu, alokację pamięci i wywołania zwrotne tylko do 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ść układu

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. Wielokrotne przejścia przez układ mogą powodować wykładniczy wzrost pracy, jeśli są wykonywane w określonych zagnieżdżonych punktach hierarchii widoku.

Jetpack Compose wymusza pojedynczy przejazd układu dla wszystkich komponentów układu za pomocą umowy dotyczącej interfejsu API. Dzięki temu Compose może efektywnie obsługiwać rozbudowane drzewa interfejsu. Jeśli potrzebne są liczne pomiary, w Compose dostępne są własne pomiary.

Wyświetlanie wydajności uruchamiania

System widoku musi napompować układy XML podczas pierwszego wyświetlania danego układu. W Jetpack Compose można zaoszczędzić na tym, ponieważ układy są pisane w Kotlinie 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ć reprezentatywne czasy, zawsze używaj wersji release zamiast wersji debug podczas profilowania aplikacji.

Aby sprawdzić wydajność kodu Jetpack Compose, możesz użyć biblioteki Jetpack Macrobenchmark. Aby dowiedzieć się, jak go używać z Jetpack Compose, zapoznaj się z projektem 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 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 ramach procesu kompilacji z wyprzedzeniem (AOT). Compose udostępnia reguły instalacji profilu, które skracają czas uruchamiania i zmniejszają zacięcia w aplikacjach Compose.