Popraw czas wczytywania początkowego, pomijając renderowanie treści poza ekranem.
Właściwość content-visibility
, która jest dostępna w Chromium 85, może być jedną z nowych właściwości CSS, które mają największy wpływ na szybkość wczytywania stron. content-visibility
umożliwia klientowi użytkownika pomijanie procesu renderowania elementu, w tym układu i malowania, dopóki nie będzie to potrzebne. Renderowanie jest pomijane, więc jeśli duża część Twoich treści znajduje się poza ekranem, wykorzystanie właściwości content-visibility
znacznie przyspiesza początkowe wczytywanie przez użytkownika. Pozwala też na szybsze interakcje z treściami na ekranie. Dobrze.
Obsługiwane przeglądarki
content-visibility
opiera się na elementach podstawowych ze specyfikacji kontenera CSS. Choć obecnie content-visibility
działa w Chromium 85 tylko w Chromium 85 (i w Firefoksie jest uznawany za „warto tworzyć prototypy”, specyfikacja zawartości jest obsługiwana w większości nowoczesnych przeglądarek.
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.
Zasadniczo programista może wskazać przeglądarce, które części strony są zawarte w zbiorze treści, co pozwala przeglądarkom analizować treść bez potrzeby uwzględniania stanu poza drzewem podrzędnym. 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 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 zapewnia, że można rozmieścić pudełko elementu bez konieczności badania jego elementów potomnych. Oznacza to, że możemy pominąć układ elementów podrzędnych, jeśli potrzebujemy tylko rozmiaru elementu.layout
: ograniczenie układu oznacza, że elementy podrzędne nie mają wpływu 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 rozłożyć inne ramki.style
: ograniczenie stylu powoduje, że właściwości, które mogą mieć wpływ nie tylko na elementy podrzędne, nie ustępują elementu (np. licznikom). Dzięki temu możemy pominąć obliczanie stylu dla elementów podrzędnych, jeśli chcemy tylko obliczać style dla innych elementów.paint
: osłonięcie farby zapobiega wyświetlaniu elementów potomnych ramki zawierającej ją poza jego granicami. Nic nie może w widoczny sposób wychodzić poza element, a jeśli element znajduje się poza ekranem lub z innego powodu nie jest widoczny, jego elementy podrzędne również nie będą widoczne. Dzięki temu możemy pominąć malowanie elementów podrzędnych, jeśli są one poza ekranem.
Pomijam renderowanie w interfejsie content-visibility
Ustalenie, których wartości obudowy należy użyć, może być trudne, ponieważ optymalizacje przeglądarek są uruchamiane tylko po określeniu odpowiedniego zestawu. Możesz eksperymentować z wartościami, aby sprawdzić, co sprawdza się najlepiej, lub użyć innej właściwości CSS o nazwie content-visibility
, aby automatycznie zastosować wymagane kontener. 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
to ta, która natychmiast poprawia wydajność. Element o stanie content-visibility: auto
zyskuje layout
, style
i paint
. Jeśli element jest poza ekranem (i nie ma znaczenia dla użytkownika – odpowiednie elementy to elementy, które mają zaznaczone elementy lub zaznaczenie w drzewie podrzędnym), uzyskuje on też size
i przerywają malowanie oraz testowanie treś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. styl i układ drzewa podrzędnego elementu.
Gdy element zbliża się do widocznego obszaru, przeglądarka nie dodaje już elementu size
i zaczyna malować i testować zawartość elementu. Dzięki temu proces renderowania może być wykonywany dokładnie w momencie, w którym będzie widoczny dla użytkownika.
Uwaga 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.
Kolejną zaletą takiego rozwiązania jest to, że elementy punktowe z takimi elementami stylu jak display: none
czy visibility: hidden
również pojawiają się w drzewie ułatwień dostępu poza ekranem, ponieważ przeglądarka nie renderuje tych stylów, dopóki nie znajdą się w widocznym obszarze. Aby zapobiec wyświetlaniu tych elementów w drzewie ułatwień dostępu (i mogą powodować bałagan), dodaj też atrybut aria-hidden="true"
.
Przykład: blog podróżniczy
Blog podróżniczy zwykle zawiera zbiór artykułów z kilkoma zdjęciami i tekstem opisowym. Standardowa przeglądarka, gdy użytkownik chce otworzyć bloga podróżniczego, wygląda tak:
- Część strony jest pobierana z sieci wraz ze wszystkimi potrzebnymi zasobami.
- Przeglądarka stylizuje i rozkłada całą zawartość strony, nie uwzględniając, czy treść jest widoczna dla użytkownika.
- Przeglądarka wraca do kroku 1, aż wszystkie strony i zasoby zostaną pobrane.
W kroku 2 przeglądarka przetwarza całą zawartość pod kątem elementów, które mogły się zmienić. 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.
Teraz zastanów się, co się stanie, jeśli dodasz content-visibility: auto
do każdego
artykułu na blogu. Ogólna pętla jest taka sama: przeglądarka pobiera i renderuje fragmenty strony. Różnica polega jednak na ilości pracy
wykonanej w kroku 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 relacji w całości poza ekranem przeglądarka pomija renderowanie i wykorzystuje tylko styl i układ pola elementu.
Wczytywanie tej strony przebiegałoby tak, jakby zawierała pełne relacje na ekranie i puste pola w każdym z nich. Zapewnia to znacznie lepsze wyniki – oczekiwany spadek kosztu renderowania wczytywania o co najmniej 50%. W naszym przykładzie widzimy wydłużenie czasu renderowania z 232 ms do 30 ms. To siedmiokrotny wzrost wydajności.
Co trzeba zrobić, aby osiągnąć te 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ą funkcji contain-intrinsic-size
Aby wykorzystać potencjalne zalety 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
rozkładany 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 kolejną właściwość contain-intrinsic-size
, która efektywnie określa naturalny rozmiar elementu, jeśli wpływ na niego ma ograniczenie rozmiaru. W naszym przykładzie ustawiamy go na 1000px
, by oszacować wysokość i szerokość sekcji.
Oznacza to, że układ będzie wyglądał tak, jakby miał pojedynczy element podrzędny o wymiarach o „rozmiarze wewnętrznym”, dzięki czemu będą one nadal zajmować przestrzeń.
contain-intrinsic-size
działa jako rozmiar obiektu zastępczego zamiast renderowanych treści.
W Chromium 98 i nowszych wersjach dodaliśmy nowe słowo kluczowe auto
dla contain-intrinsic-size
. Jeśli określisz rozmiar, przeglądarka zapamięta ostatnio wyrenderowany rozmiar (jeśli istnieje) i będzie go używać zamiast rozmiaru zastępczego dostarczonego przez dewelopera. Jeśli na przykład podasz contain-intrinsic-size: auto 300px
, element na początku w każdym wymiarze zacznie mieć rozmiar wewnętrzny 300px
, ale po wyrenderowaniu zawartości elementu zachowa on wyrenderowany rozmiar wewnętrzny.
Wszystkie późniejsze zmiany rozmiaru renderowania zostaną także zapamiętane. 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.
Ukrywanie treści w aplikacji content-visibility: hidden
Co zrobić, jeśli treści mają być nierenderowane niezależnie od tego, czy są widoczne na ekranie, jednocześnie wykorzystując zalety stanu renderowania w pamięci podręcznej? Wpisz: content-visibility: hidden
.
Właściwość content-visibility: hidden
zapewnia te same korzyści związane z nierenderowanymi treściami i stanem renderowania w pamięci podręcznej co właściwość content-visibility: auto
poza ekranem. W przeciwieństwie do obiektu auto
nie zaczyna się jednak automatycznie renderować 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 odkrycie elementu jest tak samo kosztowne jak renderowanie nowego elementu z tą samą zawartością.visibility: hidden
: ukrywa element i zachowuje stan renderowania. Nie powoduje to jednak usunięcia elementu z dokumentu, ponieważ ten element (i jego drzewo podrzędne) zajmuje jeszcze geometryczną przestrzeń na stronie i można go kliknąć. Aktualizuje też stan renderowania w każdej chwili, nawet jeśli 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 można pozostawić w modelu DOM z zastosowanym content-visibility: hidden
, aby uniemożliwić ich wyświetlanie, ale zachować 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 wartość, która określa zdolność strony do niezawodnego reagowania na dane wejściowe użytkownika. Na czas reakcji może wpływać nadmierna ilość pracy w wątku głównym, w tym prace związane z renderowaniem.
Gdy tylko możesz skrócić czas renderowania na danej stronie, dajesz wątekowi głównemu możliwość szybszego reagowania na dane wejściowe użytkownika. Obejmuje to pracę nad renderowaniem, a w razie potrzeby używanie właściwości CSS content-visiblity
może skrócić czas renderowania – szczególnie podczas uruchamiania, gdy wykonuje się większość działań związanych z renderowaniem i układem.
Skrócenie procesu renderowania ma bezpośredni wpływ na wartość INP. Gdy użytkownicy próbują prawidłowo korzystać ze strony, która używa właściwości content-visibility
, aby opóźnić układ i renderowanie elementów spoza ekranu, dajesz wątek główny szansę na reagowanie na kluczowe działania widoczne dla użytkownika. Może to w niektórych sytuacjach poprawić wartość INP strony.
Podsumowanie
content-visibility
i specyfikacja kontenera CSS oznaczają, że w Twoim pliku CSS mogą pojawić się ekscytujące wzrosty wydajności. Więcej informacji o tych właściwościach: