Unikanie zbędnych farb – animowana wersja GIF

Unikanie farb jest kluczowe dla uzyskania płynnej liczby klatek, zwłaszcza na urządzeniach mobilnych. Czasami jednak farby pojawiają się w najrzadszych miejscach. W tym artykule wyjaśniamy, dlaczego animowane GIF-y mogą powodować niepotrzebne wyrenderowania elementów, i przedstawia sposób na to niezwykle proste rozwiązanie.

Warstwy miłości

Jak pewnie wiesz, nowoczesne przeglądarki mogą malować grupy elementów DOM w osobne „obrazy”, zwane warstwami. Niekiedy może istnieć jedna warstwa na całą stronę, czasami setki, a w rzadkich przypadkach – tysiące.

Gdy elementy DOM są zgrupowane w warstwę, a jeden z nich zmienia się wizualnie, musimy malować nie tylko zmieniony element, ale także wszystkie pozostałe elementy w warstwie, które nakładają się na zmieniony element. Pomalowanie jednego elementu na drugi spowoduje, że zastąpione piksele zostaną utracone na zawsze. Jeśli chcesz przywrócić oryginalne piksele, musisz je ponownie pomalować.

Czasem chcemy odizolować jeden element od pozostałych, by po namalowaniu nie trzeba było ponownie malować tych elementów, które nie uległy zmianie. Jeśli na przykład połączysz stały nagłówek strony z treścią przewijaną, musisz ponownie wyrenderować nagłówek i treść po jego przewinięciu. Umieszczenie nagłówka w oddzielnej warstwie umożliwia optymalizowanie przewijania. Gdy przewijasz ekran, przeglądarka może przesuwać warstwy – prawdopodobnie przy użyciu GPU – i unikać ponownego malowania żadnej z nich.

Każda dodatkowa warstwa zwiększa zużycie pamięci i zmniejsza wydajność, więc celem jest zebranie strony w jak najmniejszą liczbę warstw przy zachowaniu dobrej wydajności.

Co to wszystko ma wspólnego z animowanymi GIF-ami?

Spójrzmy na ten obraz:

Aplikacja internetowa podzielona na cztery warstwy.
Rysunek 1. Aplikacja internetowa podzielona na 4 warstwy.

To jest potencjalna konfiguracja warstwy prostej dla prostej aplikacji. Istnieją tu cztery warstwy: trzy z nich (warstwy 2–4) to elementy interfejsu, a warstwa tylna to obiekt wczytujący, który jest animowanym plikiem GIF. W normalnym trybie podczas wczytywania aplikacji wyświetlany jest program wczytywania (warstwa 1), a po zakończeniu wczytywania pojawiają się pozostałe warstwy. Klucz jest jednak kluczowy: musisz ukryć animowane GIF-y.

Ale dlaczego mam to ukrywać?!

Dobre pytanie. W idealnym świecie przeglądarka po prostu sprawdza widoczność GIF-a i unika automatycznie malowania. Niestety sprawdzenie, czy animowany GIF jest zasłonięty lub widoczny na ekranie, jest zwykle droższy niż zwykłe pomalowanie go – w ten sposób zostaje malowany.

W optymalnym przypadku GIF znajduje się we własnej warstwie, a przeglądarka musi go tylko pomalować i przesłać do GPU. W najgorszym przypadku wszystkie elementy mogłyby zostać zgrupowane w jedną warstwę, a przeglądarka musi ponownie malować każdy z nich. A potem wszystko jeszcze musi przesłać na GPU. Wszystko to dzieje się w przypadku każdej klatki GIF, mimo że użytkownik nie widzi nawet GIF-a.

Na komputerach taki efekt malowania może zniknąć, ponieważ procesory i GPU są mocniejsze, a przy tym masz wystarczającą przepustowość do przesyłania danych między nimi. Na komórce malowanie jest jednak bardzo drogie, więc musisz zachować szczególną ostrożność.

W jakich przeglądarkach ta zmiana występuje?

Jak to często bywa, sposób działania przeglądarek może się różnić. Dziś Chrome, Safari i Opera są ponownie malowane, nawet jeśli GIF jest niewidoczny. Firefox z kolei wie, że GIF jest zasłonięty i nie trzeba go malować. Internet Explorer pozostaje czarnym pudełkiem, a nawet w IE11, bo wciąż pracujemy nad narzędziami F12, nic nie wskazuje na to, czy w aplikacji są malowane nowe elementy.

Jak sprawdzić, czy mam do czynienia z takim problemem?

Najłatwiejszym sposobem jest użycie opcji „Pokaż prostokąty renderowania” w Narzędziach deweloperskich w Chrome. Wczytaj Narzędzia deweloperskie, kliknij ikonę koła zębatego w prawym dolnym rogu (Ikona koła zębatego) i w sekcji Renderowanie wybierz Pokaż prostokąty renderowania.

Włączanie opcji Pokaż prostokąty renderowania w Narzędziach deweloperskich w Chrome
Rys.2: Włączanie wyświetlania prostokątów renderowania w Narzędziach deweloperskich w Chrome

Teraz wystarczy znaleźć czerwony prostokąt:

Pokaż prostokąty renderowania w Narzędziach deweloperskich wskazują, że czerwony prostokąt ma problemy z animowanymi GIF-ami.
Rys. 3: Pokazane prostokąty farby w Narzędziach deweloperskich wskazują na animowane problemy z GIF-ami za pomocą czerwonego prostokąta.

Małe czerwone pole na ekranie pokazuje, że Chrome coś odświeża. Wiesz, że za innymi elementami znajduje się ukryty plik GIF. Gdy zobaczysz takie czerwone pole, musisz ukryć widoczne elementy i sprawdzić, czy animowane GIF-y się nie obracały. Jeśli musisz, musisz wstawić kod CSS lub JavaScript, aby zastosować atrybut display: none lub visibility: hidden do niego bądź jego elementu nadrzędnego. Oczywiście, jeśli jest to tylko obraz tła, należy go usunąć.

Jeśli chcesz zobaczyć przykład takiego działania na działającej stronie, zajrzyj do Allegro, gdzie zdjęcie każdego produktu ma wczytany plik GIF, który jest zasłonięty, a nie ukryty.

Podsumowanie

Uzyskanie 60 kl./s oznacza wykonanie tylko tego, co jest potrzebne do wyrenderowania strony, bez wykonywania innych czynności. Usunięcie nadmiarowych farb jest kluczowym etapem osiągnięcia tego celu. Animowane obrazy GIF, które pozostają aktywne, mogą powodować niepotrzebne wyrenderowania, co można łatwo znaleźć i debugować za pomocą narzędzia Pokaż prostokąty renderowania w Narzędziach deweloperskich.

To nie żaden animowany GIF z kotowatym ładowarką uruchomionego w nieskończoność, prawda?