Czasy malowania CSS i waga renderowania strony

Wprowadzenie

Jeśli należysz do osób, które interesują się działaniem przeglądarek, wiesz już, że w ostatnim czasie pojawiło się kilka świetnych artykułów na temat renderowania i kompozycji przyspieszanych przez GPU w Chrome. Po pierwsze, artykuł Przyspieszone renderowanie w Chrome: model warstw to świetne wprowadzenie do tego, jak Chrome używa warstw do rysowania strony. Jeśli chcesz dowiedzieć się więcej, przeczytaj artykuł Przyspieszone komponowanie w Chrome z użyciem procesora graficznego, w którym wyjaśniamy, jak Chrome używa tych warstw i procesora graficznego do renderowania strony.

Pytanie filozoficzne

Po poświęceniu sporej ilości czasu na pisanie rasteryzatorów programowych na potrzeby grafiki 3D, zdałem sobie sprawę, że niektóre właściwości CSS powinny mieć zróżnicowaną wydajność podczas rysowania strony. Na przykład rastrowanie małego obrazu na ekranie to zupełnie inna operacja algorytmiczna niż rysowanie cienia padającego na dowolny kształt. Pytanie brzmiało: jak różne właściwości CSS wpływają na obciążenie renderowania strony?

Moim celem było pogrupowanie dużej liczby właściwości/wartości CSS według czasu renderowania, abyśmy mogli lepiej zrozumieć, które typy właściwości CSS są wydajniejsze od innych. Aby to zrobić, napisałem trochę automatyzacji z taśmą klejącą i gumą do żucia, aby spróbować dodać liczbową widoczność do czasu malowania CSS, który działał w ten sposób:

  • wygenerować zestaw pojedynczych stron HTML, z których każda zawiera pojedynczy element DOM i pewną permutację właściwości CSS;
  • Uruchom skrypt automatyzacji, który w przypadku każdej strony:
    • Uruchom Chrome
    • Wczytywanie strony
    • Utwórz obraz Skia dla strony.
    • Przeprowadź test Skia Benchmark dla każdego wykonanego zdjęcia Skia Picture, aby uzyskać czasy.
  • Wyświetl wszystkie czasy i podziwiaj te liczby. (Ta część jest ważna…)

W ramach tej konfiguracji generujemy zestaw stron HTML, z których każda zawiera unikalną kombinację właściwości i wartości CSS. Oto na przykład 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>

A 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, jako wariant ostatniego przykładu, 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>

Następnie każda strona jest wczytana do świeżego wystąpienia Chrome (aby zapewnić, że czasy nie są w żaden sposób zafałszowane przez nieaktualne stany podczas ponownego wczytywania strony), a następnie tworzony jest obraz Skia (*.SKP), aby ocenić, jakie polecenia Skia są używane do wyświetlania strony. Po wygenerowaniu plików SKP dla każdego pliku HTML uruchamiamy kolejną partię, aby przesłać pliki *.SKP do aplikacji Skia Benchmark (zbudowanej na podstawie kodu źródłowego Skia), która wyświetla średni czas potrzebny do wyrenderowania danej strony.

Ocenianie danych

Dzięki temu możemy teraz w przybliżony sposób określić, ile czasu zajmuje renderowanie zestawu właściwości CSS. Możemy też zacząć porównywać właściwości CSS według ich wydajności w zakresie malowania. Oto duży wykres wykonany w Chrome 27 w wersji beta, który pokazuje pełny zestaw danych o czasie z tego procesu. Pamiętaj, że wszystkie dane mogą ulec zmianie, ponieważ Chrome z czasem staje się coraz szybszy.

Czasy dla wszystkich permutacji w teście

Każdy pionowy pasek reprezentuje czas renderowania strony z jedną kombinacją właściwości CSS (powiększony 100 razy; rzeczywista wartość na tym wykresie to 0,156 ms). Wiele ładnych linii, ale w tej formie są one raczej bezużyteczne. Aby znaleźć przydatne trendy, musimy przeprowadzić wydobycie danych.

Po pierwsze, znaleźliśmy dowód na to, że renderowanie niektórych właściwości CSS jest po prostu droższe niż innych. Na przykład rysowanie cienia padającego na element DOM wymaga wykonania wielu przejść z użyciem krzywych Beziera i innych nieprzyjemnych rzeczy, w przeciwieństwie do przejrzystości, którą łatwiej jest renderować.

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

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

Czasy dla wszystkich permutacji w teście

Najciekawsze jest to, że nie chodzi tylko o właściwość box-shadow, ale o konkretną kombinację wartości. Poniżej pokazano na przykład grupowanie box-shadow : 50%border-radius z różnymi wartościami.

Czasy dla wszystkich permutacji w teście

Patrząc na dane, widzę, że tak jest od jakiegoś czasu. Istnieje wiele różnych kombinacji, a mój zestaw testów obejmuje tylko część z nich. Nadal jest mnóstwo testów i kombinacji, które mogą dać interesujące wyniki.

Znajdowanie wagi renderowania strony

Dzięki możliwości śledzenia czasu renderowania poszczególnych elementów na stronie deweloperzy mogą zacząć oceniać wagę renderowania strony i to, jak wpływa ona na responsywność witryny. Oto kilka wskazówek na początek

  1. Aby dowiedzieć się, które właściwości CSS są dla Ciebie kosztowne, użyj w Narzędziach dla programistów w Chrome trybu ciągłego wyświetlania.
  2. Włącz przeglądy kodu CSS do swojego dotychczasowego procesu sprawdzania kodu, aby wykrywać problemy ze skutecznością. Sprawdzaj miejsca w CSS, w których używasz elementów, które są znane jako bardziej kosztowne, np. gradientów i cieni. Zastanów się, czy na pewno są tu potrzebne.
  3. W razie wątpliwości zawsze wybieraj opcję, która zapewni lepszą wydajność. Użytkownicy mogą nie pamiętać, jaka jest szerokość marginesu kolumn, ale zapamiętają, jak się czuli podczas wizyty w Twojej witrynie.

Uwagi końcowe

Jednym z najciekawszych aspektów tego eksperymentu jest to, że czasy będą się zmieniać wraz z każdą wersją Chrome (mamy nadzieję, że będą coraz krótsze). Oprogramowanie przeglądarki to stale zmieniająca się powierzchnia. To, co dziś jest powolne, jutro może być szybkie. Z tego artykułu możesz się dowiedzieć, jak uniknąć przypisywania uprawnień box-shadow: 1px 2px 3px 4px elementom, które już mają uprawnienia border-radius:5. Bardziej wartościową lekcją jest jednak to, że właściwości CSS mają bezpośredni wpływ na czas renderowania strony.

Pliki referencyjne