Jak duże rozmiary DOM wpływają na interaktywność i co można z tym zrobić

Duże rozmiary DOM mają większy wpływ na interaktywność, niż mogłoby się wydawać. Z tego przewodnika dowiesz się, dlaczego tak się dzieje i co możesz zrobić.

Nie ma sposobu na to, aby po utworzeniu strony internetowej umieścić na niej obiektowy model dokumentu (Document Object Model, 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 możliwość szybkiego i wydajnego renderowania strony przez przeglądarkę. Ogólnie rzecz biorąc, im większy jest DOM, tym droższe jest początkowe wyrenderowanie strony, a zmiana jej renderowania w późniejszym cyklu życia strony.

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, zadbaj o to, aby rozmiary DOM były jak najmniejsze.

Kiedy DOM strony jest za duży?

Według Lighthouse rozmiar DOM strony jest zbyt duży, gdy przekracza on 1400 węzłów. Lighthouse zacznie generować ostrzeżenia, gdy DOM strony przekroczy 800 węzłów. Przykład:

<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 będzie prawie na pewno mieć o wiele więcej węzłów, dlatego warto wiedzieć, co możesz zrobić, aby kontrolować rozmiary DOM, oraz poznać inne strategie optymalizacji renderowania, gdy już uzyskasz jak najmniejszy DOM strony.

Jak duże DOM wpływają na wydajność strony?

Duże DOM wpływają na wydajność strony na kilka sposobów:

  1. Podczas wstępnego renderowania strony. Po zastosowaniu CSS na stronie tworzona jest struktura podobna do DOM, nazywana obiektowym modelem CSS (CSSOM). W miarę jak selektory arkusza CSS stają się coraz bardziej szczegółowe, CSSOM staje się coraz bardziej skomplikowany, a wykonanie pracy związanej z układem, stylem, komponowaniem i malowaniem jest niezbędne do wyświetlenia strony internetowej na ekranie, potrzeba więcej czasu. Ta dodatkowa praca wydłuża czas oczekiwania na interakcję w przypadku interakcji, które następują na wczesnym etapie wczytywania strony.
  2. Gdy interakcje modyfikują DOM, przez wstawianie lub usuwanie elementów albo przez modyfikowanie treści i stylów DOM, wyrenderowanie tej aktualizacji może skutkować bardzo kosztownymi pracami związanymi z układem, stylem, komponowaniem 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.
  3. Gdy JavaScript wysyła zapytania do DOM, odniesienia do elementów DOM są zapisywane 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.
Zrzut ekranu przedstawiający długie zadanie spowodowane nadmiernym renderowaniem w panelu wydajności w Narzędziach deweloperskich w Chrome. Stos wywołań długiego zadania pokazuje, ile czasu poświęcono na ponowne obliczanie stylów strony i wstępne wyrenderowanie.
Długie zadanie widoczne w narzędziu do profilowania wydajności w Narzędziach deweloperskich w Chrome. Wyświetlane długie zadanie jest spowodowane wstawieniem elementów DOM do dużego DOM za pomocą JavaScriptu.

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 uruchomić wiele działań, które przyczynią się do obniżenia wartości INP na stronie.

Jak mierzyć rozmiar DOM?

Rozmiar DOM można mierzyć na kilka sposobów. Pierwsza metoda korzysta z Lighthouse. Gdy przeprowadzasz audyt, statystyki DOM bieżącej strony będą wyświetlane w sekcji „Unikaj nadmiernego rozmiaru DOM”. na karcie „Diagnostyka”. nagłówek. W tej sekcji możesz zobaczyć łączną liczbę elementów DOM, elementy DOM zawierające najwięcej elementów podrzędnych oraz elementy najniższego poziomu.

Prostsza metoda polega na użyciu konsoli JavaScript w narzędziach dla programistów w dowolnej popularnej przeglądarce. Aby uzyskać łączną liczbę elementów HTML w modelu DOM, po załadowaniu strony możesz użyć w konsoli tego kodu:

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 skorelować operacje układu i stylu (oraz inne aspekty wydajności) z bieżącym rozmiarem DOM.

Zrzut ekranu przedstawiający monitor wydajności w Narzędziach deweloperskich w Chrome. Po lewej stronie widoczne są różne aspekty skuteczności strony, które można stale monitorować przez cały okres jej istnienia. Na zrzucie ekranu widać liczbę węzłów DOM, układy na sekundę i ponowne obliczenia stylów dla sekcji.
Monitor wydajności w Narzędziach deweloperskich w Chrome. W tym widoku bieżąca liczba węzłów DOM strony jest przedstawiona na wykresie wraz z operacjami dotyczącymi układu i ponownymi obliczeniami stylów w ciągu sekundy.

Jeśli rozmiar DOM zbliża się do progu ostrzegawczego rozmiaru DOM DOM – lub w ogóle się nie pojawia – kolejnym krokiem jest zaplanowanie, jak zmniejszyć rozmiar DOM, aby poprawić zdolność strony do reagowania na interakcje użytkowników i poprawić wskaźnik INP w witrynie.

Jak mogę zmierzyć liczbę elementów DOM, na które wpływa interakcja?

Jeśli profilujesz w module powolną interakcję i podejrzewasz, że może mieć to związek z rozmiarem DOM strony, możesz sprawdzić, na ile elementów DOM wpływało to działanie, wybierając w narzędziu do profilowania dowolny element aktywności o nazwie „Ponownie oblicz styl” i sprawdź dane kontekstowe w dolnym panelu.

Zrzut ekranu przedstawiający wybrane działania związane z ponownym przeliczaniem stylów w panelu wydajności w Narzędziach deweloperskich w Chrome. U góry ścieżka interakcji pokazuje interakcję z kliknięciem. Większość pracy jest poświęcona ponownemu obliczaniu stylu i wstępnym wyrenderowaniu. U dołu pojawi się panel ze szczegółowymi informacjami o wybranej aktywności, w którym widać, że wpłynęło to na 2547 elementów DOM.
Obserwowanie liczby elementów w DOM, których dotyczy problem ponownego obliczania stylu. Zwróć uwagę, że zacieniony fragment interakcji na ścieżce interakcji reprezentuje część czasu trwania interakcji, który był dłuższy niż 200 milisekund, co stanowi „dobrą” dla INP.

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 ekstremalny wpływ rozmiaru DOM na działanie renderowania na stronie z wieloma elementami DOM. Te informacje diagnostyczne przydają się jednak do określenia, czy rozmiar DOM jest czynnikiem ograniczającym czas potrzebny na wyrenderowanie następnej 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>

Takie wzorce można prawdopodobnie uprościć, spłaszczając strukturę DOM. Zmniejszy to liczbę elementów DOM i prawdopodobnie umożliwi uproszczenie stylów strony.

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.

Wiele platform pozwala jednak uniknąć zagnieżdżania komponentów przy użyciu tak zwanych fragmentów. Platformy oparte na komponentach, które oferują fragmenty jako funkcję, to m.in.:

Wykorzystując fragmenty w ramach wyboru, możesz zmniejszyć głębię DOM. Jeśli obawiasz się, że spłaszczenie struktury DOM ma wpływ na stylizację, rozważ zastosowanie bardziej nowoczesnych (i szybszych) trybów układu, takich jak flexbox czy siatka.

Inne strategie do rozważenia

Nawet jeśli z łatwością usuniesz drzewo DOM i usuniesz niepotrzebne elementy HTML, tak aby DOM był jak najmniejszy, nadal może być dość duży i wymagać sporej pracy nad renderowaniem, ponieważ zmienia się w odpowiedzi na interakcje użytkownika. Jeśli znajdujesz się w takim przypadku, istnieje kilka innych strategii, które możesz ograniczyć do renderowania.

Rozważ dodatkowe podejście

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. W takim przypadku można zastosować leniwe ładowanie kodu HTML, pomijając te części DOM podczas uruchamiania, a następnie dodawać je, gdy użytkownik wejdzie w interakcję z częściami strony, które wymagają początkowo ukrytych elementów strony.

To podejście jest przydatne zarówno podczas wczytywania początkowego, jak i może nawet 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ł. Daje to interakcjom w tym kluczowym okresie większe możliwości prowadzenia działań przy mniejszej konkurencji o uwagę w wątku głównym.

Jeśli wiele części strony jest początkowo ukrytych przy wczytywaniu, może to też przyspieszyć inne interakcje, które aktywują ponowne renderowanie. Jednak w miarę jak inne interakcje dodają charakteru DOM, nakład pracy związany z renderowaniem będzie się zwiększać wraz z rozwojem DOM w trakcie cyklu życia strony.

Dodawanie DOM w miarę upływu czasu może być kłopotliwe i wiąże się z pewnymi kompromisami. 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 pliku CSS, musi przejrzeć drzewo DOM, aby dowiedzieć się, jak i czy te selektory odnoszą się 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 wyrenderowanie strony, jak i zwiększyć liczbę ponownych obliczeń stylów i układ, jeśli strona zmieni się w wyniku interakcji.

Używanie właściwości content-visibility

CSS udostępnia właściwość content-visibility, która jest skutecznym sposobem leniwego renderowania 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 tylko do niezbędnego minimum to dobry sposób na optymalizację wartości 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 będzie zminimalizowany, a praca nad renderowaniem w odpowiedzi na interakcje użytkowników zmniejszy się. W efekcie witryna będzie bardziej elastyczna podczas interakcji z użytkownikami. Oznacza to niższy wartość INP dla witryny, co przekłada się na lepsze wrażenia użytkowników.

Baner powitalny z filmu Unsplash, Louis Reed.