Skrócenie czasu początkowego wczytywania przez pominięcie renderowania 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.
Pojemnik CSS
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. Dzięki temu, że przeglądarka wie, które fragmenty treści (poddrzewa) zawierają treści izolowane, może podejmować decyzje optymalizacyjne dotyczące renderowania strony.
Istnieją 4 typy dodatków CSS. Każdy z nich jest potencjalną wartością właściwości CSS contain
, którą można połączyć w listę 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 zapewnia, że właściwości, które mogą mieć wpływ na więcej niż tylko na jego potomków, nie wydostają się poza element (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ń renderowanie dzięki funkcji 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 Ci największą poprawę wydajności, jaką może zapewnić przeglądarka, przy minimalnym nakładzie pracy po Twojej stronie.
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ć i testować swoje zawartości).
Co to oznacza? Krótko mówiąc, jeśli element jest poza ekranem, jego elementy potomne nie są renderowane. Przeglądarka określa rozmiar elementu bez uwzględniania jego zawartości i na tej podstawie zatrzymuje się. 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ępu (w przeciwieństwie do modelu visibility: hidden
). Oznacza to, że można wyszukać tę treść na stronie i do niej przejść bez oczekiwania na jej wczytanie, a tym samym zmniejszanie 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
Blog podróżniczy zwykle zawiera zbiór artykułów z kilkoma zdjęciami i tekstem opisowym. Oto, co dzieje się w typowej przeglądarce, gdy przechodzi ona do bloga podróżniczego:
- Część strony jest pobierana z sieci wraz z wymaganymi zasobami.
- Przeglądarka stylizuje i układa wszystkie treści strony bez uwzględniania tego, czy są one widoczne dla użytkownika.
- 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 wszystkich nowych elementów oraz elementów, które mogły się przesunąć w wyniku nowych aktualizacji. To jest renderowanie. To może trochę potrwać.
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.
W przypadku widoczności treści styl i układ będą dotyczyć wszystkich treści, które są obecnie widoczne dla użytkownika (znajdują się na ekranie). Jednak podczas przetwarzania historii, która jest całkowicie poza ekranem, przeglądarka pomija renderowanie i stylizuje oraz układa tylko element.
Prędkość wczytywania tej strony byłaby taka sama, jak gdyby zawierała pełne historie na ekranie i puste pola dla każdej z historii poza ekranem. 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:
Następnie stosujemy tę regułę stylu do tych sekcji:
.story {
content-visibility: auto;
contain-intrinsic-size: 1000px; /* Explained in the next section. */
}
Określanie naturalnego rozmiaru elementu za pomocą atrybutu contain-intrinsic-size
Aby w pełni wykorzystać możliwości content-visibility
, przeglądarka musi zastosować ograniczenie rozmiaru, aby wyniki renderowania treści w żaden sposób nie wpływały na rozmiar elementu. Oznacza to, że element będzie wyglądał tak, jakby był pusty. Jeśli element nie ma określonej wysokości w zwykłym układzie bloku, jego wysokość będzie wynosić 0.
Może to nie być idealne, ponieważ rozmiar paska przewijania będzie się zmieniał w zależności od tego, czy każda historia ma wysokość niezerową.
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 zaaplikowanym content-visibility: auto
, a potem przewiniesz go z powrotem poza ekran, zachowa on automatycznie idealną szerokość i wysokość, a nie wróci do rozmiaru placeholdera. Ta funkcja jest szczególnie przydatna w przypadku nieskończonego przewijania, które może teraz automatycznie poprawiać szacowanie rozmiaru w czasie, gdy użytkownik przegląda stronę.
Ukryj treść: 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.
Daje to większą kontrolę, pozwalając na ukrycie zawartości elementów i ich szybkie ich ukrycie.
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.
Z drugiej strony, właściwość content-visibility: hidden
ukrywa element, zachowując jednocześnie jego stan renderowania. Oznacza to, że jeśli trzeba wprowadzić jakieś zmiany, nastąpi to dopiero wtedy, gdy element zostanie ponownie wyświetlony (czyli zostanie usunięta właściwość content-visibility: hidden
).
content-visibility: hidden
sprawdza się w przypadku stosowania zaawansowanych wirtualnych kółek przewijania i pomiaru układu. Są też świetne do 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 szybko renderowany, 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.
Zmniejszenie obciążenia związanego z renderowaniem ma bezpośredni wpływ na 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: