Czasy malowania CSS i waga renderowania strony

Wprowadzenie

Jeśli interesujesz się tym, jak działają przeglądarki, to pewnie wiesz, że ostatnio pojawiło się kilka świetnych artykułów szczegółowo opisujących działanie renderera/kompozytu Chrome przyspieszanego przez GPU. Po pierwsze, artykuł Accelerated Rendering in Chrome: The Layer Model (Przyspieszone renderowanie w Chrome: model warstwowy) stanowi świetne wprowadzenie do tego, jak Chrome wykorzystuje koncepcję warstw do rysowania strony. Po drugie, artykuł GPU Accelerated Compositing in Chrome (Kompozycja przyspieszana przez GPU w Chrome) zawiera szczegółowe omówienie tego, jak Chrome wykorzystuje te warstwy wraz z GPU do renderowania strony.

Pytanie filozoficzne

Poświęciłem sporo czasu na pisanie rasteryzatorów oprogramowania do celów 3D i zdałem sobie sprawę, że niektóre właściwości CSS powinny mieć różną wydajność podczas renderowania strony. Na przykład rasteryzacja małego obrazu na ekranie to zupełnie inna operacja algorytmiczna niż rysowanie cienia z cieniem na dowolnym kształcie. Pytanie brzmi: jak różne właściwości CSS wpływają na wagę renderowania strony?

Moim celem było skategoryzowanie dużego zestawu właściwości i wartości CSS według czasu renderowania, abyśmy mogli zrozumieć, które typy właściwości CSS są bardziej wydajne od innych. Aby to zrobić, napisałem kilka automatyzacji, które miały na celu dodanie liczbowej widoczności do czasów renderowania CSS. Działało to tak:

  • wygenerować zestaw pojedynczych stron HTML, z których każda zawiera jeden element DOM i pewną permutację dołączonych do niego właściwości CSS;
  • Uruchom skrypt automatyzacji, który dla każdej strony:
    • Uruchom Chrome
    • Wczytywanie strony
    • wygenerować obraz Skia dla strony,
    • Uruchom każdy obraz Skia Picture w Skia Benchmark, aby uzyskać czasy.
  • Wyświetl wszystkie czasy i podziwiaj liczby. (To ważna część…)

W tej konfiguracji generujemy zestaw stron HTML, z których każda zawiera unikalną permutację właściwości i wartości CSS. Oto 2 pliki HTML:

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

i drugi, bardziej złożony.

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Poniżej znajduje się wariant ostatniego przykładu, w którym zmieniamy tylko wartość gradientu promieniowego:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

Każda strona jest następnie wczytywana w nowej instancji Chrome (aby mieć pewność, że na czas nie wpłynęły żadne nieaktualne stany podczas ponownego wczytywania strony), a następnie jest wykonywany obraz Skia (*.SKP), aby ocenić, jakie polecenia Skia są używane do renderowania strony. Po wygenerowaniu plików SKP dla każdego pliku HTML uruchamiamy kolejną partię, aby przesłać pliki *.SKP przez aplikację Skia Benchmark (utworzoną na podstawie kodu źródłowego Skia), która podaje średni czas renderowania danej strony.

Analiza danych

Dzięki temu możemy teraz w przybliżeniu określić, ile czasu zajmuje renderowanie zestawu właściwości CSS. Możemy zacząć układać właściwości CSS według ich wydajności renderowania. Oto duży wykres utworzony w Chrome 27 beta, który przedstawia pełny zestaw danych o czasie trwania tego procesu. Pamiętaj, że wszystkie dane mogą ulec zmianie, ponieważ Chrome z czasem działa coraz szybciej.

Czasy wszystkich permutacji w teście

Każdy pionowy słupek reprezentuje czas renderowania strony z jedną kombinacją właściwości CSS (powiększony 100 razy; rzeczywista skala tego wykresu to 0–1,56 ms). Wiele ładnych linii, ale w tej formie są one bezużyteczne. Musimy przeprowadzić analizę danych, aby znaleźć przydatne trendy.

Po pierwsze, okazuje się, że niektóre właściwości CSS są po prostu bardziej kosztowne do renderowania niż inne. Na przykład rysowanie cienia na elemencie DOM wymaga wieloetapowej operacji z użyciem krzywych i innych skomplikowanych elementów, podczas gdy renderowanie przezroczystości powinno być łatwiejsze.

Czas potrzebny na wyrenderowanie elementu, który ma tylko 1 właściwość CSS

Po drugie, co jest bardziej interesujące, kombinacje właściwości CSS mogą mieć dłuższy czas renderowania niż suma ich części. Z perspektywy obserwatora jest to nieco dziwne, ponieważ spodziewalibyśmy się, że A + B = C, a nie 2,2 C. Na przykład dodanie box-shadow i border-radius-stroke :

Czasy wszystkich permutacji w teście

Co ciekawe, nie chodzi tu o samą właściwość box-shadow, ale o konkretną permutację wartości. Poniżej pokazujemy na przykład grupowanie atrybutów box-shadow : 50% i border-radius z różnymi wartościami.

Czasy wszystkich permutacji w teście

Z danych wynika, że trwa to już od dłuższego czasu. Istnieje wiele różnych dziwnych kombinacji, a mój zestaw testów obejmuje tylko niektóre z nich. Nadal jest mnóstwo testów i kombinacji, które mogą przynieść interesujące wyniki.

Znajdowanie wagi renderowania strony

Dzięki możliwości śledzenia czasu renderowania każdego elementu na stronie deweloperzy mogą zacząć oceniać wagę renderowania strony i jej wpływ na responsywność witryny. Oto kilka wskazówek na początek:

  1. Użyj trybu ciągłego renderowania w Narzędziach deweloperskich w Chrome, aby dowiedzieć się, które właściwości CSS są najbardziej obciążające.
  2. Uwzględnij inspekcję kodu CSS w istniejącym procesie inspekcji kodu, aby wykrywać problemy z wydajnością. Szukaj w kodzie CSS miejsc, w których używasz elementów, które są bardziej wymagające, takich jak gradienty i cienie. Zastanów się, czy naprawdę potrzebujesz tych informacji.
  3. W razie wątpliwości zawsze wybieraj lepszą wydajność. Użytkownicy mogą nie pamiętać, jaka jest szerokość dopełnienia w kolumnach, ale będą pamiętać, jakie wrażenie zrobiła na nich Twoja witryna.

Uwagi końcowe

Jedną z najciekawszych rzeczy w tym eksperymencie jest to, że czasy będą się zmieniać z każdą wersją Chrome (mamy nadzieję, że będą coraz krótsze ;)). Oprogramowanie przeglądarki to stale zmieniający się obszar. To, co dziś jest wolne, jutro może być szybkie. Możesz usunąć z tego artykułu, aby uniknąć umieszczania box-shadow: 1px 2px 3px 4px w elemencie, który ma już border-radius:5. Jednak ważniejszym wnioskiem jest to, że właściwości CSS bezpośrednio wpływają na czas renderowania strony.

Odniesienia