Optymalizacja skuteczności obrazów

Praca z obrazami może szybko wywołać problemy z wydajnością. Podczas pracy z dużymi mapami bitowymi można dość łatwo natrafić na OutOfMemoryError. Postępuj zgodnie z tymi sprawdzonymi metodami, aby Twoja aplikacja działała jak najlepiej.

Wczytywanie tylko potrzebnej bitmapy

Większość smartfonów ma aparaty o wysokiej rozdzielczości, które pozwalają tworzyć duże pliki graficzne. Jeśli chcesz wyświetlać obraz na ekranie, musisz zmniejszyć jego rozdzielczość lub wczytywać go tylko do rozmiaru kontenera obrazów. Ciągłe wczytywanie większych niż potrzebnych obrazów może wyczerpać pamięć podręczną GPU, co prowadzi do mniej wydajnego renderowania interfejsu.

Aby zarządzać rozmiarami obrazów:

Tam, gdzie to możliwe, używaj wektorów zamiast map bitowych

Prezentując coś wizualnie na ekranie, musisz zdecydować, czy da się to przedstawić w formie wektorowej. Wolisz obrazy wektorowe zamiast map bitowych, ponieważ nie pikselują się przy skalowaniu do różnych rozmiarów. Jednak nie wszystko da się przedstawić w formie wektorowej – obrazów zrobionych aparatem nie da się przekonwertować na format wektorowy.

Podaj alternatywne zasoby dla ekranów o różnych rozmiarach

Jeśli wraz z aplikacją przesyłasz obrazy, rozważ przesłanie zasobów w różnych rozmiarach dla różnych rozdzielczości urządzeń. Dzięki temu możesz zmniejszyć rozmiar pobieranej aplikacji na urządzenia i zwiększyć jej wydajność, ponieważ na urządzeniach o niższej rozdzielczości obrazy będą wczytywane w niższej rozdzielczości. Więcej informacji o udostępnianiu alternatywnych map bitowych na potrzeby urządzeń o różnych rozmiarach znajdziesz w dokumentacji alternatywnych map bitowych.

Jeśli używasz narzędzia ImageBitmap, przed rysowaniem wywołaj prepareToDraw

Jeśli używasz ImageBitmap, aby rozpocząć proces przesyłania tekstury do GPU, wywołaj ImageBitmap#prepareToDraw(), zanim zaczniesz jej rysować. Pomaga to GPU przygotować teksturę i poprawia wydajność wyświetlania elementów wizualnych na ekranie. Większość bibliotek wczytywania obrazów już przeprowadza tę optymalizację, ale jeśli samodzielnie pracujesz z klasą ImageBitmap, musisz o tym pamiętać.

Wolisz przekazać do funkcji kompozycyjnej Int DrawableRes lub URL jako parametry zamiast Painter

Ze względu na złożoność pracy z obrazami (np. wpisanie funkcji równości w przypadku Bitmaps może być kosztowne pod względem obliczeniowym), dlatego interfejs API Painter nie jest wyraźnie oznaczony jako klasa stabilna. Niestabilne klasy mogą prowadzić do niepotrzebnych zmian kompozycji, ponieważ kompilator nie jest w stanie łatwo określić, czy dane uległy zmianie.

Dlatego zaleca się przekazywanie adresu URL lub identyfikatora zasobu rysowalnego jako parametrów do funkcji kompozycyjnej zamiast Painter jako parametru.

// Prefer this:
@Composable
fun MyImage(url: String) {

}
// Over this:
@Composable
fun MyImage(painter: Painter) {

}

Nie zapisuj bitmapy w pamięci dłużej, niż jest to potrzebne

Im więcej map bitowych wczytuje się do pamięci, tym większe jest prawdopodobieństwo, że na urządzeniu zabraknie pamięci. Jeśli na przykład wczytujesz na ekranie dużą listę elementów kompozycyjnych obrazu, użyj LazyColumn lub LazyRow, aby mieć pewność, że przy przewijaniu dużej listy zostanie zwolniona pamięć.

Nie pakuj dużych obrazów za pomocą pliku AAB/APK

Jedną z najczęstszych przyczyn dużego rozmiaru pobierania aplikacji jest umieszczenie grafiki w pliku pakietu AAB lub APK. Użyj Analizatora plików APK, aby upewnić się, że nie wielkość pakietu przekracza wymagane pliki graficzne. Zmniejsz rozmiar lub rozważ umieszczenie obrazów na serwerze i pobieranie ich tylko wtedy, gdy to konieczne.