Przyspiesz początkowe wczytywanie, pomijając renderowanie treści poza ekranem.
Wprowadzona w Chromium w wersji 85 właściwość content-visibility
może być jedną z najbardziej przydatnych nowych usług CSS zwiększających szybkość wczytywania stron. content-visibility
umożliwia klientowi użytkownika pominięcie renderowania elementu, w tym układu i malowania, do momentu, aż będzie to potrzebne. Renderowanie jest pomijane, więc jeśli duża część treści znajduje się poza ekranem, użycie właściwości content-visibility
znacznie przyspiesza początkowe wczytywanie. Umożliwia to też szybsze interakcje
z treściami na ekranie. Całkiem porządnie.
Obsługiwane przeglądarki
content-visibility
opiera się na elementach podstawowych zgodnych ze specyfikacją CSS. Choć content-visibility
jest obecnie obsługiwany tylko w Chromium 85 (i w Firefoksie jest uznawany za „wartościowe prototypowanie”), specyfikacja o stopniu opanowana jest obsługiwana w większości nowoczesnych przeglądarek.
Kontener CSS
Najważniejszym i nadrzędnym celem izolacji arkusza CSS jest umożliwienie zwiększenia wydajności renderowania treści internetowych przez zapewnienie przewidywalnej izolacji poddrzewa DOM od reszty strony.
Programista może powiedzieć przeglądarce, które części strony są zawarte w formie zbioru treści, dzięki czemu przeglądarka może odpowiednio zorientować się w treści, nie martwiąc się o stan poza drzewem. Wiedząc, które fragmenty treści (poddrzewa) zawierają izolowane treści, przeglądarka może podejmować decyzje dotyczące optymalizacji renderowania strony.
Istnieją 4 typy zawartości CSS. Każda potencjalna wartość właściwości CSS contain
, którą można połączyć na liście wartości rozdzielonych spacjami:
size
: ukrycie rozmiaru elementu umożliwia jego nałożenie bez konieczności sprawdzania jego elementów podrzędnych. Oznacza to, że możemy potencjalnie pominąć układ elementów podrzędnych, jeśli potrzebujemy tylko rozmiaru elementu.layout
: ograniczenie układu oznacza, że elementy podrzędne nie wpływają na zewnętrzny układ innych pól na stronie. Dzięki temu możemy pominąć układ elementów podrzędnych, jeśli chcemy tylko rozmieścić inne pudełka.style
: ograniczanie stylu sprawia, że właściwości, które mogą mieć wpływ na nie tylko jego elementy podrzędne, nie opuszczają elementu (np. liczniki zdarzeń). Dzięki temu możemy pominąć obliczanie stylu dla elementów podrzędnych, jeśli chcemy obliczać style na innych elementach.paint
: powłoka malowana gwarantuje, że elementy potomne pola, w którym się znajdują, nie będą wyświetlać się poza jego granicami. Nic nie może w widoczny sposób przemienić się z elementu. Jeśli element znajduje się poza ekranem lub w inny sposób nie jest widoczny, jego elementy potomne również nie będą widoczne. Dzięki temu możemy pominąć malowanie elementów potomnych, jeśli element znajduje się poza ekranem.
Pomijanie renderowania za pomocą funkcji content-visibility
Określenie właściwych wartości ograniczania może być trudne, ponieważ optymalizacja przeglądarki może zacząć działać dopiero po określeniu odpowiedniego zestawu danych. Możesz wypróbować wartości, aby sprawdzić, co działa najlepiej, lub użyć innej właściwości CSS o nazwie content-visibility
, aby automatycznie zastosować wymagany element składowy. content-visibility
zapewnia maksymalną wydajność, jaką przeglądarka może zapewnić przy minimalnym nakładzie pracy ze strony dewelopera.
Właściwość content-visibility może przyjmować kilka wartości, ale auto
to ta, która zapewnia natychmiastową poprawę wydajności. Element, który ma właściwość content-visibility: auto
, zyskuje ograniczenie przez layout
, style
i paint
. Jeśli element znajduje się poza ekranem (i w inny sposób nie jest odpowiedni dla użytkownika – stosownym elementem są elementy, na których zaznaczono lub zaznaczono element w poddrzewie), użytkownik zyskuje również powłokę size
(i przestaje obrazować i testować zawartość strony).
Co to oznacza? Krótko mówiąc, jeśli element znajduje się poza ekranem, jego elementy potomne nie są renderowane. Przeglądarka określa rozmiar elementu, nie biorąc pod uwagę jego zawartości, i zatrzymuje się na tym etapie. Większość renderowania, np. styl i układ drzewa podrzędnego elementu, jest pomijana.
Gdy element zbliża się do widocznego obszaru, przeglądarka nie dodaje już komponentu size
i zaczyna malować oraz testować jego zawartość. Dzięki temu renderowanie można wykonać w odpowiednim momencie.
Uwaga na temat ułatwień dostępu
Jedną z funkcji content-visibility: auto
jest to, że treść poza ekranem pozostaje dostępna w modelu obiektu dokumentu, a tym samym w drzewie ułatwień dostępu (w odróżnieniu od visibility: hidden
). Oznacza to, że treści można wyszukiwać na stronie i do niej przechodzić bez czekania na jej wczytanie czy pogorszenie wydajności renderowania.
Z kolei znaki wyróżniające z elementami stylu, takimi jak display: none
czy visibility: hidden
, również pojawią się na drzewie ułatwień dostępu poza ekranem, ponieważ przeglądarka nie będzie renderować tych stylów, dopóki nie znajdą się w widocznym obszarze. Aby nie były one widoczne w drzewie ułatwień dostępu, co mogłoby powodować bałagan, dodaj też atrybut aria-hidden="true"
.
Przykład: blog podróżniczy
Blog podróżny zawiera zwykle zbiór artykułów z kilkoma zdjęciami i tekstem. Oto, co dzieje się w typowej przeglądarce po przejściu do bloga podróżniczego:
- Z sieci jest pobierana część strony wraz ze wszystkimi potrzebnymi zasobami.
- Przeglądarka określa styl i układa całą zawartość strony bez uwzględniania, czy treść jest widoczna dla użytkownika.
- Przeglądarka cofa się do kroku 1, aż cała strona i wszystkie zasoby zostaną pobrane.
W drugim kroku przeglądarka przetwarza całą zawartość, szukając rzeczy, które mogły się zmienić. Aktualizuje styl i układ wszystkich nowych elementów, a także te, które mogły się przesunąć w wyniku aktualizacji. To tylko renderowanie. To wymaga czasu.
Zastanówmy się, co się stanie, jeśli do każdego artykułu dodasz content-visibility: auto
. Ogólna pętla jest taka sama: przeglądarka pobiera i renderuje fragmenty strony. Różnica tkwi jednak w ilości
pracy wykonanej w kroku 2.
Dzięki temu określisz styl i układ wszystkich treści, które są aktualnie widoczne dla użytkownika (są wyświetlane na ekranie). Podczas przetwarzania historii, która w pełni wykracza poza ekran, przeglądarka pomija renderowanie, a jedynie styl i układ pola z elementami.
Wczytanie strony wyglądałoby tak, jakby zawierała pełne artykuły na ekranie i puste pola przy każdym z nich. Działa to znacznie lepiej, ale spodziewane jest zmniejszenie kosztu renderowania o co najmniej 50%. W naszym przykładzie zaobserwowaliśmy wydłużenie czasu renderowania z 232 ms do 30 ms. To siedmiokrotny wzrost skuteczności.
Co musisz zrobić, aby zyskać te korzyści? Najpierw dzielimy treści na sekcje:
Następnie stosujemy do tych sekcji następującą regułę stylu:
.story {
content-visibility: auto;
contain-intrinsic-size: 1000px; /* Explained in the next section. */
}
Określanie naturalnego rozmiaru elementu za pomocą funkcji contain-intrinsic-size
Aby uwolnić potencjalne korzyści, jakie daje content-visibility
, przeglądarka musi zastosować ograniczanie rozmiaru, aby zapewnić, że wyniki renderowania treści nie wpływają w żaden sposób na rozmiar elementu. Oznacza to, że element będzie wyglądał tak,
jakby był pusty. Jeśli element nie ma wysokości określonej w zwykłym układzie bloków, będzie miał 0 wysokości.
Nie jest to idealne rozwiązanie, ponieważ rozmiar paska przewijania będzie się zmieniał, ponieważ wysokość każdego artykułu jest różna od zera.
Na szczęście CSS udostępnia kolejną właściwość – contain-intrinsic-size
, która efektywnie określa naturalny rozmiar elementu, o ile ogranicza on rozmiar. W naszym przykładzie ustawimy go na 1000px
, czyli szacunkową wysokość i szerokość sekcji.
Oznacza to, że będzie się wyświetlać tak, jakby miał jeden element podrzędny o wymiarach „własnych”, dzięki czemu elementy div bez określonego rozmiaru nadal zajmują miejsce.
contain-intrinsic-size
pełni rolę symbolu zastępczego zamiast renderowanej treści.
W Chromium od wersji 98 pojawiło się nowe słowo kluczowe auto
dla aplikacji contain-intrinsic-size
. Gdy zostanie on określony, przeglądarka zapamięta ostatnio wyrenderowany rozmiar (jeśli był) i użyje go zamiast rozmiaru obiektu zastępczego podanego przez dewelopera. Jeśli np. podasz wartość contain-intrinsic-size: auto 300px
, element będzie się zaczynał od rozmiaru wewnętrznego 300px
w każdym wymiarze, ale po wyrenderowaniu jego zawartości zachowa on wyrenderowany wewnętrzny rozmiar.
Zapamiętywane są też wszystkie późniejsze zmiany rozmiaru renderowania. W praktyce oznacza to, że jeśli przewiniesz element z zastosowaną wartością content-visibility: auto
, a potem przewiniesz go z powrotem poza ekran, automatycznie zachowa on idealną szerokość i wysokość oraz nie powraca do rozmiaru zmiennej. Ta funkcja jest szczególnie przydatna w przypadku przewijania nieskończonego, ponieważ może z czasem automatycznie zwiększać oszacowanie rozmiaru, gdy użytkownik przegląda stronę.
Ukrywam treści w aplikacji content-visibility: hidden
Co zrobić, jeśli chcesz, aby treści nie były renderowane niezależnie od tego, czy są widoczne na ekranie, a jednocześnie chcesz wykorzystać zalety stanu renderowania w pamięci podręcznej? Wpisz:
content-visibility: hidden
.
Właściwość content-visibility: hidden
zapewnia te same zalety nierenderowanych treści i stanu renderowania w pamięci podręcznej co content-visibility: auto
poza ekranem. Jednak w przeciwieństwie do auto
nie zaczyna się automatycznie renderować na ekranie.
Daje to większą kontrolę, ponieważ pozwala ukrywać zawartość elementów i później szybko je odkrywać.
Porównaj to z innymi popularnymi sposobami ukrywania zawartości elementów:
display: none
: ukrywa element i niszczy jego stan renderowania. Oznacza to, że odkrycie elementu jest tak samo kosztowne jak renderowanie nowego elementu o tej samej treści.visibility: hidden
: ukrywa element i zachowuje stan renderowania. Nie spowoduje to faktycznego usunięcia elementu z dokumentu, ponieważ (i jest ono poddrzewem) nadal zajmuje geometryczne miejsce na stronie i można go kliknąć. Aktualizuje też stan renderowania za każdym razem, gdy jest potrzebny, nawet gdy jest ukryty.
content-visibility: hidden
jednak ukrywa element, zachowując jego stan renderowania, więc jeśli trzeba wprowadzić jakieś zmiany, nastąpi to tylko po ponownym wyświetleniu elementu (tzn. po usunięciu właściwości content-visibility: hidden
).
Użycie content-visibility: hidden
może być szczególnie przydatne przy implementowaniu zaawansowanych wirtualnych przewijań i pomiaru układu. Świetnie sprawdzają się też
w aplikacjach jednostronicowych. Nieaktywne widoki aplikacji można pozostawić w DOM z zastosowaniem content-visibility: hidden
, aby zapobiec ich wyświetlaniu, ale zachować ich stan w pamięci podręcznej. Dzięki temu widok będzie się szybciej renderować, gdy stanie się ponownie aktywny.
Wpływ na interakcję z kolejnym wyrenderowaniem (INP)
INP to wskaźnik określający zdolność strony do niezawodnego reagowania na dane wejściowe użytkownika. Na szybkość reagowania wpływa nadmierna ilość pracy wykonywanej w wątku głównym, w tym praca z renderowaniem.
Jeśli możesz skrócić czas renderowania na danej stronie, dajesz wątkowi głównemu możliwość szybszego reagowania na dane wejściowe użytkownika. Obejmuje to renderowanie, a stosowanie właściwości CSS content-visiblity
w stosownych przypadkach może ograniczyć czas renderowania – szczególnie podczas uruchamiania, gdy wykonuje się większość czynności związanych z renderowaniem i układem.
Zmniejszenie ilości pracy związanej z renderowaniem ma bezpośredni wpływ na wartość INP. Gdy użytkownicy próbują wejść w interakcję ze stroną, która używa właściwości content-visibility
w celu odroczenia układu i renderowania elementów poza ekranem, dajesz wątkowi głównemu szansę zareagowania na ważne działania widoczne dla użytkowników. W niektórych sytuacjach może to poprawić wartość INP strony.
Podsumowanie
content-visibility
i specyfikacja zawartości CSS oznaczają, że w Twoim pliku CSS wkrótce pojawi się kilka ciekawych ulepszeń dotyczących wydajności. Więcej informacji o tych właściwościach: