Critical CSS, czy się opłaca?
SOA#1 – to zależy
Od wielu czynników, m.in. tego jaki jest stan początkowy. I o tym dziś opowiem.
W piątek pojawił się cotygodniowy newsletter od unteam, w którym był link do narzędzia pozwalającego na wydobycie ze strony tzw. Critical CSS. Pobawiłem się nim trochę przy współpracy Dżepetto i mam kilka wniosków. Po kolei…
Critical CSS, co to?
Założenie jest następujące. Przeglądarki wczytują i renderują kontent od góry do dołu, inaczej mówiąc, przetwarzają HTML strumieniowo. Jeżeli natkną się na plik CSS, to go pobiorą. Jak trafią na nieznany plik z fontami, to go pobiorą. I tak też będą renderować zawartość strony. Najpierw wyrenderują to co jest widoczne, potem przejdą dalej. Procesem tym możemy sterować na wiele różnych sposobów. Możemy używać cache, możemy używać prefetch i preload. Możemy w końcu zadbać o to, żeby zasoby potrzebne do wyrenderowania strony były dostępne jak najwcześniej. I tu właśnie wchodzi Critical CSS. Jest to podzbiór reguł CSS używanych na danej stronie, które aplikują się do tej części strony, która będzie widoczna jako pierwsza.
Jak umieścić CSS na stronie?
Mamy dwa wyjścia (poza stylowaniem elementów ad-hoc). Możemy użyć tagu <style>
w kodzie html lub możemy użyć <link>
i wskazać plik z arkuszem
stylu. Jeżeli wykorzystamy pierwszą metodę, to style zostaną przesłane wraz ze stroną, to zwiększa objętość dokumentu, ale zmniejszy liczbę żądań (
pomijam użycie cache). Kłopotliwe może być jednak utrzymanie spójnych styli pomiędzy różnymi dokumentami, ale to pomijalna kwestia, bo zakładam, że
wykorzystujemy jakiś generator, a nie lecimy z palca w notepadzie. Druga metoda ładnie nam separuje style i dokument. Pozwala na użycie cache i
całkiem zgrabne zarządzanie całością. Wadą jest ten nieszczęsny dodatkowy request, który czasami chcemy wykonań, a czasami niekoniecznie.
Ważne jednak jest też to w którym miejscu w kodzie stony umieścimy nasze znaczniki.
Critical CSS, jak działa?
Pomysł jest następujący. W nagłówku dokumentu, czyli w <head>
umieszczamy znacznik <style>
zawierający nasz krytyczny arkusz stylów. Przeglądarka,
przystępując do renderowania, nie musi czekać na zewnętrzny arkusz. W dodatku jest to „minimal effective sheet”, czyli arkusz zawierający tylko
potrzebne style w dodatku w ich efektywnej postaci, czyli w czasie ich aplikacji nie będzie następować nadpisywanie (cascade). Nasze właściwe style w
postaci <link>
umieszczmy przed znacznikiem </body>
. Zostaną pobrane na samym końcu, zmniejszając „First Contentful Paint”, czyli czas jaki upływa
do momentu wyrenderowania pierwszego elemantu na stronie. Mówiąc po ludzku, czas, po jakim użytkownik zobaczy, że coś się załadowało.
Praktyka
Korzystając z narzędzia z newslettera oraz przy małej pomocy Dżepetto przystąpiłem do wdrożenia tej techniki na blogasku. Pierwszym krokiem było określenie stanu obecnego. W tym celu wykorzystałem PageSpeed Insights i przygotowałem pierwszy raport. Jest bardzo dobrze. FCP na poziomie 0,4s dla desktopa i 1,5s dla mobilków, to dobry wynik. Kolejnym krokiem były wygenerowanie zestawu styli oraz podpięcie ich do bloga. Wygenerowałem więc zestaw dla strony głównej i kilku pierwszych artykułów. Następnie Dżepetto przetworzył je, wybierając część wspólną, sotrując wg. kolejności użycia, a na koniec zminifikował całość. Wysłałem i gotowe. Po chwili przygotowałem kolejny raport. I dupa. Okazało się, że wydajność strony spadła. FCP nie zmienił się, ale pojawił się problem z „Cumulative Layout Shift”.
Cumulative Layout Shift, co to?
Jest to metryka, która mówi, jak bardzo wygląd strony, zmienia się w czasie jej ładowania. Po ludzku, jak bardzo strona skacze „po załadowaniu”, czyli jak bardzo wkurza użytkownika. Tutaj wkurzał bardzo. Wartość 0,648 dla desktopu i 0,399 dla mobilki są dalekie od akceptowalnych. Szczególnie, że wcześniej wynosiły 0.
W efekcie wycofałem zmianę i parametry wróciły do normy.
Jeszcze inne podejście.
A co jeżeli potraktować cały arkusz css jako krytyczny? Korzystam z Jekylla, więc przynajmniej teoretycznie nie powinno być problemu z osadzeniem
styli na stronie w elemencie <style>
. Powtórzyłem więc zabawę, tym razem wstawiając cały css w nagłówek. Spowodowało to znaczne powiększenie
wielkości dokumentu, co jest takie sobie. Z 15kb mamy nagle 35kb, a w dodatku średnio możemy używać cache, ale jakoś to ogarnę definicjami <meta>
.
Efekty były… cóż średnio zadowalające, o ile na dektopie raport nie
wykazał zmian, to już na wersji mobilnej wydajność spadła. Zmianę wycofałem.
Podsumowanie
Dobra wiadomość jest taka, że z blogaska już zbyt wiele nie wycisnę, jeśli chodzi o wydajność :D Critical CSS jest ciekawym rozwiązaniem, ale trzeba mierzyć, mierzyć i jeszcze raz mierzyć, bo zamiast polepszyć, można popieprzyć. Wiem też, że brakuje mi wiedzy o nowoczesnych narzędziach, choć nie boli to aż tak bardzo. Nie jestem webmasterem ani frontasiem. Z rzeczy do zrobienia jest jeszcze ogarnięcie trackingu, ale to już zupełnie inna bajka.