Jeśli zauważysz problemy z wydajnością wynikające z niepotrzebnego lub nadmiernego ponownego komponowania, musisz debugować stabilność aplikacji. W tym przewodniku znajdziesz kilka metod, które Ci w tym pomogą.
[narzędzie] Layout Inspector
Inspektor układu w Android Studio pozwala sprawdzić, które funkcje kompozycyjne są ponownie komponowane w aplikacji. Wyświetla on liczbę ponownych kompozycji lub pominięć komponentu przez Compose.
Tworzenie raportów kompilatora
Kompilator Compose może wyświetlać wyniki wnioskowania o stabilności do sprawdzenia. Na podstawie tych danych możesz określić, które funkcje kompozycyjne można pominąć, a których nie. W podsekcjach poniżej znajdziesz podsumowanie informacji o tym, jak korzystać z tych raportów. Więcej szczegółów znajdziesz w dokumentacji technicznej.
Konfiguracja
Raporty kompilatora Compose nie są domyślnie włączone. Możesz je aktywować za pomocą flagi kompilatora. Dokładna konfiguracja zależy od projektu, ale w przypadku projektów korzystających z wtyczki Gradle kompilatora Compose możesz dodać poniższy kod w pliku build.gradle
każdego modułu.
android { ... }
composeCompiler {
reportsDestination = layout.buildDirectory.dir("compose_compiler")
metricsDestination = layout.buildDirectory.dir("compose_compiler")
}
Podczas kompilowania projektu będą teraz generowane raporty kompilatora Compose.
Przykładowe dane wyjściowe
Funkcja reportsDestination
zwraca 3 pliki. Poniżej przedstawiamy przykładowe dane wyjściowe z JetSnack.
<modulename>-classes.txt
: raport o stabilności klas w tym module. Próbka<modulename>-composables.txt
: raport o tym, czy funkcje kompozycyjne w module można ponownie uruchamiać i pomijać. Próbka<modulename>-composables.csv
:CSV
wersja raportu o komponentach, którą możesz zaimportować do arkusza kalkulacyjnego lub przetworzyć za pomocą skryptu. Próbka
Raport funkcji kompozycyjnych
Plik composables.txt
zawiera szczegółowe informacje o każdej funkcji kompozycyjnej w danym module, w tym stabilność jej parametrów oraz to, czy można ją ponownie uruchomić lub pominąć. Oto hipotetyczny przykład z JetSnack:
restartable skippable scheme("[androidx.compose.ui.UiComposable]") fun SnackCollection(
stable snackCollection: SnackCollection
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
stable index: Int = @static 0
stable highlight: Boolean = @static true
)
Ten komponent SnackCollection
można w pełni ponownie uruchomić, pominąć i jest on stabilny. Jest to zazwyczaj preferowane, ale nie jest obowiązkowe.
Z drugiej strony spójrzmy na inny przykład.
restartable scheme("[androidx.compose.ui.UiComposable]") fun HighlightedSnacks(
stable index: Int
unstable snacks: List<Snack>
stable onSnackClick: Function1<Long, Unit>
stable modifier: Modifier? = @static Companion
)
Funkcji HighlightedSnacks
nie można pominąć. Compose nigdy nie pomija tego elementu podczas ponownego komponowania. Dzieje się tak nawet wtedy, gdy żaden z parametrów nie uległ zmianie.
Przyczyną jest parametr unstable
, snacks
.
Raport Zajęcia
Plik classes.txt
zawiera podobny raport dotyczący klas w danym module. Poniższy fragment to dane wyjściowe klasy Snack
:
unstable class Snack {
stable val id: Long
stable val name: String
stable val imageUrl: String
stable val price: Long
stable val tagline: String
unstable val tags: Set<String>
<runtime stability> = Unstable
}
Dla przypomnienia podajemy definicję Snack
:
data class Snack(
val id: Long,
val name: String,
val imageUrl: String,
val price: Long,
val tagline: String = "",
val tags: Set<String> = emptySet()
)
Kompilator Compose oznaczył Snack
jako niestabilny. Dzieje się tak, ponieważ typ parametru tags
to Set<String>
. Jest to typ niezmienny, ponieważ nie jest to MutableSet
. Standardowe klasy kolekcji, takie jak Set
, List
i Map
, są jednak interfejsami. Dlatego bazowa implementacja może być nadal modyfikowalna.
Możesz na przykład napisać val set: Set<String> = mutableSetOf("foo")
. Zmienna jest stała, a jej zadeklarowany typ jest niezmienny, ale jej implementacja nadal może ulegać zmianom. Komplilator Compose nie ma pewności, czy ta klasa jest niezmienna, ponieważ widzi tylko zadeklarowany typ. Dlatego oznacza
tags
jako niestabilny.