content-visibility: nowa właściwość CSS, która zwiększa wydajność renderowania;

Popraw czas wczytywania początkowego, pomijając renderowanie treści poza ekranem.

Data publikacji: 5 sierpnia 2020 r.

Właściwość content-visibility umożliwia klientowi użytkownika pomijanie procesu renderowania elementu, w tym układu i malowania, dopóki nie będzie to potrzebne. Jeśli duża część treści znajduje się poza ekranem, renderowanie jest pomijane, a użycie właściwości content-visibility powoduje, że początkowe wczytywanie przez użytkownika jest znacznie szybsze. Pozwala też na szybsze interakcje z treściami na ekranie. Bardzo fajnie.

Obsługa przeglądarek

  • Chrome: 85.
  • Edge: 85.
  • Firefox: 125.
  • Safari: 18.

Źródło

Demo z wykresami przedstawiającymi wyniki sieci
W naszym demonstracyjnym artykule zastosowanie content-visibility: auto do podzielonych obszarów treści zwiększa wydajność renderowania podczas początkowego wczytywania o 7 razy. Aby dowiedzieć się więcej, czytaj dalej.

Ograniczenie do usługi porównywania cen

Głównym i nadrzędnym celem powstrzymania kodu CSS jest zwiększenie wydajności renderowania treści internetowych przez zapewnienie przewidywalnej izolacji poddrzewa DOM od reszty strony.

Programista może poinformować przeglądarkę, które części strony są zaszyfrowane jako zestaw treści, co pozwala przeglądarce analizować te treści bez konieczności uwzględniania stanu poza poddrzewem. Wiedza o tym, które elementy (poddrzewa) treści zawierają wyodrębnioną treść, umożliwia przeglądarce podejmowanie decyzji dotyczących optymalizacji pod kątem renderowania stron.

Istnieją 4 typy obejmu CSS: każda z nich to potencjalna wartość właściwości CSS contain, którą można łączyć na liście wartości oddzielonych spacjami:

  • size: ograniczenie rozmiaru elementu sprawia, że można rozmieścić pole elementu bez konieczności sprawdzania jego potomków. Oznacza to, że możemy pominąć układ potomków, jeśli interesuje nas tylko rozmiar elementu.
  • layout: ograniczenie układu oznacza, że elementy potomne nie wpływają na zewnętrzny układ innych pól na stronie. Dzięki temu możemy pominąć układ potomków, jeśli chcemy tylko ustawić inne pola.
  • style: ograniczenie stylu powoduje, że właściwości, które mogą mieć wpływ nie tylko na elementy podrzędne, nie uciekną przed elementem (np. liczniki). Dzięki temu możemy pominąć obliczanie stylu dla elementów podrzędnych, jeśli chcemy tylko obliczać style dla innych elementów.
  • paint: ograniczenie obszaru powoduje, że potomkowie elementu kontenera nie będą wyświetlać się poza jego granicami. Element nie może być widoczny poza obszarem ekranu. Jeśli element jest poza ekranem lub w inny sposób niewidoczny, jego potomkowie również nie będą widoczni. Dzięki temu możemy pominąć wyświetlanie potomków, jeśli element znajduje się poza ekranem.

Pomiń zadanie renderowania w programie content-visibility

Trudno jest określić, których wartości ograniczania użyć, ponieważ optymalizacje przeglądarki mogą zadziałać dopiero po określeniu odpowiedniego zbioru. Możesz eksperymentować z wartościami, aby sprawdzić, które działają najlepiej, lub użyć content-visibility, aby automatycznie zastosować potrzebne ograniczenie. content-visibility zapewnia największy wzrost wydajności, jaki może zapewnić przeglądarka przy minimalnym nakładzie pracy programistów.

Właściwość content-visibility akceptuje kilka wartości, ale auto zapewnia natychmiastowe zwiększenie skuteczności. Element, który ma atrybuty content-visibility: auto, zyskuje atrybuty layout, style i paint. Jeśli element znajduje się poza ekranem (i nie jest istotny dla użytkownika – istotne elementy to te, które są aktywne lub wybrane w swoim poddrzewie), jest też ograniczony do size (i przestaje renderowaćtestować swoje zawartości).

Co to oznacza? Krótko mówiąc, jeśli element jest poza ekranem, jego potomkowie nie są renderowane. Przeglądarka określa rozmiar elementu bez uwzględniania jego zawartości. Pomijana jest większość renderowania, np. stylizacja i układ poddrzewa elementu.

Gdy element zbliża się do widocznego obszaru, przeglądarka przestaje dodawać ograniczenie size i zaczyna wyświetlać oraz testować zawartość elementu. Dzięki temu renderowanie zostanie wykonane w optymalnym momencie, aby użytkownik mógł zobaczyć wynik.

Uwagi na temat ułatwień dostępu

Jedną z funkcji content-visibility: auto jest to, że treści poza ekranem pozostają dostępne w modelu obiektu dokumentu, a tym samym w drzewie ułatwień dostępności (w przeciwieństwie do visibility: hidden). Oznacza to, że można wyszukiwać treści na stronie i do nich przechodzić bez oczekiwania na ich załadowanie lub poświęcania wydajności renderowania.

Z drugiej strony elementy punktu odniesienia z funkcjami stylu, takie jak display: none lub visibility: hidden, będą też widoczne w drzewie ułatwień dostępu, gdy są poza ekranem, ponieważ przeglądarka nie będzie renderować tych stylów, dopóki nie znajdą się w widoku. Aby te elementy nie były widoczne w drzewie dostępności i nie powodowały bałaganu, dodaj też aria-hidden="true".

Przykład: blog podróżniczy

W tym przykładzie po prawej stronie umieściliśmy blog podróżniczy, a po lewej – obszary podzielone na części za pomocą funkcji content-visibility: auto. Wyniki pokazują, że czas renderowania podczas początkowego wczytywania strony zmniejszył się z 232 ms do 30 ms.

Blog podróżniczy zawiera zwykle kilka artykułów z kilkoma zdjęciami i tekstem opisowym. Oto co dzieje się w typowej przeglądarce, gdy użytkownik chce odwiedzać bloga o podróżach:

  1. Część strony jest pobierana z sieci wraz z wymaganymi zasobami.
  2. Przeglądarka stylizuje i rozkłada całą zawartość strony, nie uwzględniając, czy treść jest widoczna dla użytkownika.
  3. Przeglądarka wraca do kroku 1, aż wszystkie strony i zasoby zostaną pobrane.

W kroku 2 przeglądarka przetwarza wszystkie treści, szukając elementów, które mogły ulec zmianie. Aktualizuje styl i układ nowych elementów, a także te, które mogły się przesunąć w wyniku aktualizacji. To jest renderowanie. To wymaga czasu.

Zrzut ekranu bloga podróżniczego.
Przykład bloga podróżniczego. Zobacz prezentację na Codepen

Zastanów się, co się stanie, jeśli dodasz content-visibility: auto do poszczególnych artykułów na blogu. Ogólna pętla jest taka sama: przeglądarka pobiera i renderuje fragmenty strony. Różnica polega jednak na tym, ile pracy wykonuje on na etapie 2.

Widoczność treści określa styl i układ całej zawartości, która jest aktualnie widoczna dla użytkownika (są one widoczne na ekranie). Jednak podczas przetwarzania historii, która jest całkowicie poza ekranem, przeglądarka pomija renderowanie i stylizuje oraz układa tylko element.

Wczytywanie tej strony przebiegałoby tak, jakby zawierała pełne relacje na ekranie i puste pola w każdym z nich. Ta metoda działa znacznie lepiej, ponieważ oczekujemy 50-procentowego zmniejszenia kosztu renderowania podczas wczytywania. W naszym przykładzie czas renderowania skrócił się z 232 ms do 30 ms. To wzrost wydajności o 7 razy.

Jakie działania należy wykonać, aby skorzystać z tych korzyści? Najpierw dzielimy treści na sekcje:

Zrzut ekranu z treściami podzielonymi na sekcje za pomocą klasy CSS.
Przykład dzielenia treści na sekcje z zastosowaną klasą story w celu otrzymania content-visibility: auto. Zobacz prezentację na Codepen

Następnie stosujemy do sekcji tę regułę stylu:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

Określ naturalny rozmiar elementu za pomocą atrybutu contain-intrinsic-size

Aby wykorzystać potencjalne korzyści, jakie daje content-visibility, przeglądarka musi zastosować ograniczenie rozmiaru, aby wyniki renderowania treści nie wpływały w żaden sposób na rozmiar elementu. Oznacza to, że element będzie wyglądał tak, jakby był pusty. Jeżeli wysokość elementu nie jest określona w zwykłym układzie blokowym, będzie on miał wysokość 0.

Nie jest to idealne rozwiązanie, ponieważ rozmiar paska przewijania będzie się zmieniać, co oznacza, że każdy artykuł ma wysokość inną niż zero.

Na szczęście CSS udostępnia inną właściwość, contain-intrinsic-size, która określa domyślny rozmiar elementu jeśli element jest ograniczony rozmiarem. W naszym przykładzie ustawiamy wartość 1000px jako szacunek wysokości i szerokości sekcji.

Oznacza to, że będzie ono rozmieszczane tak, jak gdyby miało pojedynczy element podrzędny o wymiarach „intrinsic-size”, co zapewni, że elementy div bez rozmiaru nadal będą zajmować miejsce. contain-intrinsic-size pełni funkcję obiektu zastępczego zamiast renderowanych treści.

Słowo kluczowe auto dla contain-intrinsic-size powoduje, że przeglądarka zapamięta ostatni renderowany rozmiar (jeśli taki istnieje) i użyje go zamiast rozmiaru placeholdera podanego przez dewelopera. Jeśli na przykład określisz wartość contain-intrinsic-size: auto 300px, element będzie mieć początkowo rozmiar 300px w każdym wymiarze, ale po wyrenderowaniu jego zawartości zachowa renderowany rozmiar. Zapamiętane zostaną też wszystkie kolejne zmiany rozmiaru renderowania. W praktyce oznacza to, że jeśli przewiniesz element z zastosowaną właściwością content-visibility: auto, a potem przewiniesz go z powrotem poza ekran, automatycznie zachowa on idealną szerokość i wysokość – nie zostanie przywrócony rozmiar obiektu zastępczego. Ta funkcja jest szczególnie przydatna w przypadku użytkowników przewijających nieskończoność ekranu, które mogą teraz automatycznie poprawiać oszacowanie rozmiaru w miarę przeglądania strony przez użytkownika.

Ukryj treści, w których występuje content-visibility: hidden

Co zrobić, jeśli chcesz zachować nieprzetworzone treści niezależnie od tego, czy są one widoczne na ekranie, i jednocześnie korzystać z zalet stanu renderowania w pamięci podręcznej? Wpisz: content-visibility: hidden.

Usługa content-visibility: hidden zapewnia te same korzyści, co content-visibility: auto, w zakresie nieprzetworzonych treści i stanu renderowania w pamięci podręcznej, gdy nie wyświetla się na ekranie. Jednak w odróżnieniu od auto nie jest on automatycznie renderowany na ekranie.

Dzięki temu masz większą kontrolę i możesz ukryć zawartość elementu, a później szybko ją odsłonić.

Porównaj to z innymi typowymi sposobami ukrywania zawartości elementu:

  • display: none: ukrywa element i niszczy jego stan renderowania. Oznacza to, że odsłonięcie elementu jest tak samo kosztowne jak wyrenderowanie nowego elementu z tymi samymi treściami.
  • visibility: hidden: ukrywa element, zachowując stan renderowania. Nie powoduje to jednak rzeczywistego usunięcia elementu z dokumentu, ponieważ on (i jego poddrzewo) nadal zajmuje geometryczną przestrzeń na stronie i nadal można go kliknąć. Aktualizuje też stan renderowania w razie potrzeby, nawet gdy jest ukryty.

content-visibility: hidden ukrywa element z zachowaniem jego stanu renderowania.Jeśli więc trzeba wprowadzić jakieś zmiany, zostaną one wprowadzone tylko przy ponownym wyświetleniu elementu (tzn. gdy właściwość content-visibility: hidden zostanie usunięta).

content-visibility: hidden znakomicie sprawdza się przy implementowaniu zaawansowanych wirtualnych mechanizmów przewijania czy pomiarze układu. Świetnie sprawdzają się też w przypadku aplikacji jednostronicowych (SPA). Nieaktywne widoki aplikacji mogą pozostać w DOM z aplikacją content-visibility: hidden, aby zapobiec ich wyświetlaniu, ale zachować ich stan w pamięci podręcznej. Dzięki temu widok będzie się szybko renderować, gdy znów stanie się aktywny.

Wpływ na interakcję do kolejnego wyrenderowania (INP)

INP to dane, które oceniają, jak szybko i bezbłędnie strona reaguje na działania użytkowników. Szybkość działania może być ograniczana przez nadmierną ilość pracy wykonywanej w wątku głównym, w tym renderowanie.

Gdy uda Ci się zmniejszyć ilość pracy związanej z renderowaniem na danej stronie, zyskasz czas na szybszą reakcję wątku głównego na działania użytkownika. Dotyczy to renderowania. Właściwa obsługa właściwości content-visiblity w CSS może zmniejszyć obciążenie renderowaniem, zwłaszcza podczas uruchamiania, gdy większość pracy związanej z renderowaniem i układem jest już wykonana.

Skrócenie procesu renderowania ma bezpośredni wpływ na wartość INP. Gdy użytkownicy próbują wchodzić w interakcję ze stroną, która prawidłowo używa właściwości content-visibility do opóźniania układu i renderowania elementów poza ekranem, główny wątek ma możliwość zareagowania na ważne działania widoczne dla użytkownika. Może to w niektórych sytuacjach poprawić wartość INP strony.

Podsumowanie

content-visibility i specyfikacja ograniczania CSS oznaczają, że wkrótce wprowadzimy w pliku CSS kilka ciekawych ulepszeń dotyczących wydajności. Więcej informacji o tych właściwościach znajdziesz w tych artykułach: