Duże rozmiary DOM mają większy wpływ na interaktywność, niż Ci się wydaje. Z tego przewodnika dowiesz się, dlaczego tak się dzieje i co możesz zrobić.
Nie ma innej możliwości: gdy tworzysz stronę internetową, ta strona będzie miała model dokumentu (DOM). DOM reprezentuje strukturę kodu HTML strony i daje JavaScript i CSS dostęp do jej struktury i treści.
Problem polega jednak na tym, że rozmiar DOM wpływa na szybkość i skuteczność renderowania strony przez przeglądarkę. Ogólnie rzecz biorąc, im większy jest DOM, tym droższe jest początkowe renderowanie strony i aktualizowanie jej renderowania w późniejszym etapie jej cyklu życia.
Stanowi to problem na stronach z bardzo dużymi modelami DOM, gdy interakcje, które modyfikują lub aktualizują DOM, inicjują kosztowne prace związane z układem, które wpływają na zdolność strony do szybkiego reagowania. Wymagające prace związane z układem mogą mieć wpływ na interakcję z następnym wyrenderowaniem (INP). Jeśli chcesz, aby strona szybko reagowała na interakcje użytkowników, upewnij się, że rozmiary DOM są tylko niezbędne.
Kiedy DOM strony jest za duży?
Według Lighthouse rozmiar DOM strony jest zbyt duży, gdy przekracza 1400 węzłów. Lighthouse zacznie generować ostrzeżenia, gdy DOM strony przekroczy 800 węzłów. Weźmy na przykład kod HTML:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
Powyższy kod zawiera 4 elementy DOM: element <ul>
i 3 jego elementy podrzędne <li>
. Twoja strona internetowa będzie prawie na pewno miała znacznie więcej węzłów, dlatego warto wiedzieć, jak kontrolować rozmiary DOM. Warto też znać inne strategie optymalizacji renderowania, gdy już zminimalizujesz DOM strony.
Jak duże DOM wpływają na wydajność strony?
Duże DOM-y wpływają na wydajność strony na kilka sposobów:
- Podczas początkowego renderowania strony. Po zastosowaniu CSS na stronie tworzona jest struktura podobna do DOM, zwana CSS Object Model (CSSOM). Im bardziej szczegółowe są selektory arkusza CSS, tym bardziej złożony jest obiekt CSSOM, a tym więcej czasu zajmuje wykonanie niezbędnych czynności związanych z układem, stylami, kompozycją i malowaniem, które są potrzebne do wyświetlenia strony internetowej na ekranie. To dodatkowe działanie zwiększa opóźnienie interakcji, które występują na początku wczytywania strony.
- Gdy interakcje modyfikują DOM, np. przez wstawianie lub usuwanie elementów albo modyfikowanie zawartości i stylów DOM, konieczne do renderowania zmiany mogą wiązać się z bardzo kosztowną pracą nad układem, stylami, kompozycją i malowaniem. Tak jak w przypadku początkowego wyrenderowania strony, zwiększenie precyzji selektora arkusza CSS może zwiększyć wydajność renderowania, gdy w wyniku interakcji elementy HTML zostaną wstawione do modelu DOM.
- Gdy JavaScript wysyła zapytanie do DOM, odwołania do elementów DOM są przechowywane w pamięci. Jeśli na przykład wywołasz metodę
document.querySelectorAll
, aby zaznaczyć wszystkie elementy<div>
na stronie, koszt pamięci może być znaczny, jeśli wynik zwróci dużą liczbę elementów DOM.
Wszystkie te czynniki mogą wpływać na interaktywność, ale szczególnie ważna jest druga pozycja na liście powyżej. Jeśli interakcja powoduje zmianę DOM, może to wywołać wiele działań, które mogą przyczynić się do niskiej wartości INP na stronie.
Jak mierzyć rozmiar DOM?
Rozmiar DOM można mierzyć na kilka sposobów. Pierwsza metoda korzysta z Lighthouse. Gdy przeprowadzisz kontrolę, statystyki DOM bieżącej strony zostaną uwzględnione w audycie „Unikaj nadmiernego rozmiaru DOM” w sekcji „Diagnostyka”. W tej sekcji możesz zobaczyć łączną liczbę elementów DOM, element DOM zawierający najwięcej elementów podrzędnych, a także element DOM znajdujący się najgłębiej w strukturze.
Prostszą metodą jest użycie konsoli JavaScriptu w narzędziach dla programistów w dowolnej popularnej przeglądarce. Aby poznać łączną liczbę elementów HTML w DOM, możesz użyć tego kodu w konsoli po załadowaniu strony:
document.querySelectorAll('*').length;
Jeśli chcesz sprawdzać rozmiar DOM w czasie rzeczywistym, możesz też użyć narzędzia do monitorowania wydajności. Za pomocą tego narzędzia możesz powiązać operacje dotyczące układu i stylu (oraz inne aspekty wydajności) z aktualnym rozmiarem DOM.
Jeśli rozmiar DOM zbliża się do progu ostrzeżenia dotyczącego rozmiaru DOM w Lighthouse lub nie spełnia go w ogóle, następnym krokiem będzie znalezienie sposobu na zmniejszenie rozmiaru DOM, aby zwiększyć zdolność strony do reagowania na interakcje użytkowników, co pozwoli poprawić INP witryny.
Jak mogę zmierzyć liczbę elementów DOM, na które wpływa interakcja?
Jeśli w laboratorium profilujesz wolno działającą interakcję, która według Ciebie może mieć związek z rozmiarem DOM strony, możesz sprawdzić, ile elementów DOM zostało dotknięte. W tym celu wybierz w profilu dowolny element aktywności oznaczony etykietą „Ponownie oblicz styl” i obserwuj dane kontekstowe w dolnym panelu.
Na zrzucie ekranu powyżej zobacz, że ponowne obliczenie stylu utworu – po jego wybraniu – pokazuje liczbę elementów, których dotyczy problem. Powyższy zrzut ekranu pokazuje skrajne przypadki wpływu rozmiaru DOM na renderowanie strony z dużą liczbą elementów DOM, ale te informacje diagnostyczne są przydatne w każdym przypadku, aby określić, czy rozmiar DOM jest czynnikiem ograniczającym czas potrzebny na wyrenderowanie kolejnego klatki w odpowiedzi na interakcję.
Jak zmniejszyć rozmiar DOM?
Oprócz sprawdzania kodu HTML witryny pod kątem zbędnych znaczników głównym sposobem na zmniejszenie rozmiaru DOM jest zmniejszenie głębi DOM. Jednym z sygnałów, że Twój DOM może być niepotrzebnie głęboki, jest to, że na karcie Elementy w narzędziach dla programistów w przeglądarce widzisz znaczniki, które wyglądają mniej więcej tak:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Gdy widzisz takie wzorce, możesz je uprościć, spłaszając strukturę DOM. Dzięki temu zmniejszysz liczbę elementów DOM i prawdopodobnie zyskasz możliwość uproszczenia stylów stron.
Objawem może też być głębia DOM. W szczególności platformy oparte na komponentach (np. oparte na JSX) wymagają zagnieżdżenia wielu komponentów w kontenerze nadrzędnym.
Jednak wiele frameworków umożliwia unikanie zagnieżdżania komponentów dzięki fragmentom. Oto niektóre frameworki oparte na komponentach, które oferują fragmenty jako funkcję:
Wykorzystując fragmenty w ramach wyboru, możesz zmniejszyć głębię DOM. Jeśli obawiasz się, jaki wpływ na styl będzie mieć spłaszczenie struktury DOM, skorzystaj z nowoczesnych (i szybszych) trybów układu, takich jak flexbox czy siatka.
Inne strategie do rozważenia
Nawet jeśli postarasz się spłaszczyć drzewo DOM i usunąć zbędne elementy HTML, aby zachować jak najmniejszą możliwą wielkość DOM, to nadal może ono być dość duże i wymagać dużej pracy związanej z renderowaniem, gdy zmienia się w odpowiedzi na działania użytkownika. Jeśli tak się stanie, możesz zastosować inne strategie, aby ograniczyć renderowanie.
Rozważ podejście polegające na dodawaniu
Być może znajdujesz się w miejscu, w którym duże fragmenty strony nie są początkowo widoczne dla użytkownika przy pierwszym renderowaniu. Może to być okazja do opóźnionego wczytywania kodu HTML przez pominięcie tych części DOM podczas uruchamiania, ale dodanie ich, gdy użytkownik wejdzie w interakcję z częściami strony, które wymagają początkowo ukrytych aspektów strony.
Takie podejście jest przydatne zarówno podczas początkowego wczytywania, jak i później. Podczas początkowego wczytywania strony mniej czasu poświęcasz na renderowanie, co oznacza, że początkowy ładunek HTML będzie lżejszy i będzie szybciej się renderował. Dzięki temu w tym kluczowym okresie interakcje będą miały więcej możliwości, a jednocześnie będą musiały konkurować o uwagę w wątku głównym.
Jeśli masz wiele części strony, które są początkowo ukryte podczas wczytywania, może to przyspieszyć inne interakcje, które powodują ponowne renderowanie. Jednak w miarę jak inne interakcje wnoszą większy wkład do DOM, nakład pracy związany z renderowaniem będzie się zwiększać wraz z rozwojem DOM w trakcie cyklu życia strony.
Dodawanie elementów do DOM-u z upływem czasu może być trudne i wymagać kompromisów. Jeśli idziesz tą drogą, prawdopodobnie wysyłasz żądania sieciowe, które w odpowiedzi na interakcję użytkownika przesyłają dane do kodu HTML, który chcesz dodać do strony. Chociaż przesyłane żądania sieciowe nie są wliczane do INP, mogą zwiększyć postrzegane opóźnienie. Jeśli to możliwe, wyświetlaj wskaźnik ładowania lub inny wskaźnik ładowania danych, aby użytkownicy wiedzieli, że coś się dzieje.
Ogranicz złożoność selektora arkusza CSS
Gdy przeglądarka analizuje selektory w arkuszu CSS, musi przejść przez drzewo DOM, aby zrozumieć, jak i czy te selektory mają zastosowanie do bieżącego układu. Im bardziej złożone są te selektory, tym więcej pracy musi wykonać przeglądarka, aby przeprowadzić zarówno początkowe renderowanie strony, jak i częstsze ponowne obliczanie stylów oraz pracę nad układem, jeśli strona zmienia się w wyniku interakcji.
Używanie właściwości content-visibility
CSS udostępnia właściwość content-visibility
, która umożliwia leniwe renderowanie pozaekranowych elementów DOM. Gdy elementy zbliżają się do widocznego obszaru, są renderowane na żądanie. Zalety content-visibility
nie tylko eliminują znaczne części pracy związanej z renderowaniem podczas wstępnego renderowania strony, ale także pomijają renderowanie elementów poza ekranem, gdy DOM strony zmienia się w wyniku interakcji użytkownika.
Podsumowanie
Zmniejszenie rozmiaru DOM do niezbędnego minimum to dobry sposób na optymalizację INP witryny. W ten sposób możesz skrócić czas potrzebny przeglądarce na renderowanie i wyświetlanie układu po zaktualizowaniu DOM. Nawet jeśli nie możesz w znacznym stopniu zmniejszyć rozmiaru DOM, możesz zastosować pewne techniki rozdzielające renderowanie od poddrzewa DOM, np. osłoną CSS i właściwość CSS content-visibility
.
Niezależnie od tego, jak się za to zabierzesz, stwórz środowisko, w którym nakład pracy związany z renderowaniem zostanie zminimalizowany, a praca nad renderowaniem w odpowiedzi na interakcje użytkowników zmniejszy się. W efekcie witryna będzie bardziej reagująca na interakcje użytkowników z użytkownikami. Oznacza to niższy wartość INP dla witryny, co przekłada się na lepsze wrażenia użytkowników.