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

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.

demonstracja z rysunkami reprezentującymi wyniki dotyczące sieci
W naszym artykule demonstracyjnym zastosowanie content-visibility: auto do fragmentów treści pozwala siedmiokrotnie zwiększyć wydajność renderowania przy wstępnym wczytaniu. Czytaj dalej, aby dowiedzieć się więcej.

Obsługiwane przeglądarki

Obsługa przeglądarek

  • 85
  • 85
  • 124

Źródło

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

W tym przykładzie po prawej stronie znajduje się blog o podróżach, a po prawej – element content-visibility: auto – do fragmentów tekstu po lewej stronie. Wyniki pokazują czas renderowania strony od 232 ms do 30 ms przy pierwszym wczytaniu strony.

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:

  1. Z sieci jest pobierana część strony wraz ze wszystkimi potrzebnymi zasobami.
  2. Przeglądarka określa styl i układa całą zawartość strony bez uwzględniania, czy treść jest widoczna dla użytkownika.
  3. 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.

Zrzut ekranu z blogiem podróżniczym.
Przykład bloga o podróżach. Zobacz Demo na Codepen

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:

Zrzut ekranu z adnotacjami przedstawiającymi podział treści na sekcje za pomocą klasy CSS.
Przykład podzielenia treści na sekcje z zastosowaną klasą story w celu otrzymania content-visibility: auto. Zobacz Demo na Codepen

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: