Optymalizacja skuteczności obrazów

Jeśli nie będziesz uważać, praca z obrazami może szybko spowodować problemy z wydajnością. Podczas pracy z dużymi bitmapami możesz łatwo napotkać problem OutOfMemoryError. Stosuj te sprawdzone metody, aby zapewnić optymalną wydajność aplikacji.

Ładuj tylko potrzebny rozmiar bitmapy

Większość smartfonów ma aparaty o wysokiej rozdzielczości, które generują duże pliki graficzne. Jeśli wyświetlasz obraz na ekranie, musisz zmniejszyć jego rozdzielczość lub załadować obraz tylko do rozmiaru kontenera. Ciągłe wczytywanie obrazów większych niż to potrzebne może wyczerpywać pamięć podręczną karty graficznej, co prowadzi do gorszego renderowania interfejsu.

Aby zarządzać rozmiarami obrazów:

  • Zmniejsz rozmiar plików obrazów do możliwie najmniejszego (bez wpływu na obraz wyjściowy).
  • Rozważ konwersję obrazów na format WEBP zamiast JPEG lub PNG.
  • Prześlij mniejsze obrazy w przypadku różnych rozdzielczości ekranu (patrz wskazówka 3),
  • Użyj biblioteki wczytywania obrazów, która zmniejsza obraz, aby pasował do rozmiaru widoku na ekranie. Może to poprawić wydajność wczytywania ekranu.

W miarę możliwości używaj wektorów zamiast bitmap.

Przedstawiając coś wizualnie na ekranie, musisz zdecydować, czy można to przedstawić jako wektor. Zamiast bitmap stosuj obrazy wektorowe, ponieważ nie stają się one pikselowe, gdy przeskalujesz je do różnych rozmiarów. Nie wszystko jednak można przedstawić jako wektor – obrazów wykonanych za pomocą aparatu nie można przekonwertować na wektor.

Przesyłanie zasobów alternatywnych na potrzeby różnych rozmiarów ekranu

Jeśli przesyłasz obrazy wraz z aplikacją, rozważ dostarczenie zasobów o różnych rozmiarach na potrzeby różnych rozdzielczości urządzeń. Pomoże to zmniejszyć rozmiar pliku do pobrania aplikacji na urządzeniach i poprawić wydajność, ponieważ na urządzeniu o niższej rozdzielczości wczytywane będą obrazy o niższej rozdzielczości. Więcej informacji o zapewnianiu bitmap alternatywnych na potrzeby różnych rozmiarów urządzeń znajdziesz w dokumentacji bitmap alternatywnych.

Jeśli używasz ImageBitmap, przed narysowaniem okna wywołaj funkcję prepareToDraw.

Jeśli używasz ImageBitmap, przed rozpoczęciem przesyłania tekstury do karty graficznej wywołaj funkcję ImageBitmap#prepareToDraw(), zanim ją narysujesz. Pomaga to procesorowi graficznemu przygotować teksturę i poprawić wydajność wyświetlania elementów wizualnych na ekranie. Większość bibliotek do ładowania obrazów już stosuje tę optymalizację, ale jeśli pracujesz z klasą ImageBitmap, musisz o tym pamiętać.

Zamiast Painter do parametrów w komponowalnym elemencie warto przekazać Int DrawableRes lub URL.

Ze względu na złożoność obsługi obrazów (np. napisanie funkcji równania dla Bitmaps byłoby kosztowne pod względem obliczeniowym) interfejs API Painter nie jest wyraźnie oznaczony jako klasa stabilna. Niestabilne klasy mogą prowadzić do niepotrzebnych ponownych kompilacji, ponieważ kompilator nie może łatwo określić, czy dane uległy zmianie.

Dlatego lepiej jest przekazać URL lub identyfikator zasobu rysowanego jako parametry do składanego komponentu zamiast przekazywać parametr Painter.

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

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

}

Nie przechowuj bitmapy w pamięci dłużej niż to konieczne.

Im więcej bitmap wczytasz do pamięci, tym większe jest prawdopodobieństwo, że zabraknie Ci pamięci na urządzeniu. Jeśli na przykład wczytujesz na ekranie dużą listę komponentów ImageComposables, użyj opcji LazyColumn lub LazyRow, aby zwolnić pamięć podczas przewijania dużej listy.

Nie pakuj dużych obrazów w pliku AAB lub APK

Jedną z głównych przyczyn dużego rozmiaru pobierania aplikacji są grafiki zapakowane w pliku AAB lub APK. Użyj narzędzia analizatora pliku APK, aby sprawdzić, czy nie pakujesz plików obrazów większych niż wymagane. Zmniejsz rozmiary lub rozważ umieszczenie obrazów na serwerze i pobieranie ich tylko wtedy, gdy jest to konieczne.