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ć. Ten przewodnik wyjaśnia, dlaczego i co możesz zrobić.

Nie da się go obejść: jeśli utworzysz stronę internetową, będzie ona miała DOM. DOM reprezentuje strukturę kodu HTML strony oraz daje skryptom JavaScript i CSS dostęp do struktury i zawartości strony.

Problem polega jednak na tym, że rozmiar DOM wpływa na zdolność przeglądarki do szybkiego i efektywnego renderowania strony. Ogólnie rzecz biorąc, im większy jest model DOM, tym droższe jest początkowe wyrenderowanie strony i zaktualizowanie jej renderowania na późniejszym etapie cyklu życia.

Staje się to problematyczne na stronach z bardzo dużymi modelami DOM, gdy interakcje, które modyfikują lub aktualizują DOM, uruchamiają kosztowne prace układu, które utrudniają szybką reagowanie. Wysokie nakłady pracy związane z układem mogą wpływać na interakcje z kolejnym 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 element DOM strony jest za duży?

Według narzędzia Lighthouse rozmiar DOM strony jest nadmierny, gdy przekracza 1400 węzłów. Lighthouse zacznie generować ostrzeżenia, gdy DOM strony przekroczy 800 węzłów. Przeanalizujmy ten przykładowy kod HTML:

<ul>
  <li>List item one.</li>
  <li>List item two.</li>
  <li>List item three.</li>
</ul>

W powyższym kodzie znajdują się 4 elementy DOM: element <ul> i jego 3 elementy podrzędne <li>. Strona internetowa niemal na pewno będzie miała znacznie więcej węzłów, dlatego ważne jest, aby zrozumieć, co zrobić, aby mieć kontrolę nad rozmiarami DOM, a także inne strategie optymalizacji pracy renderowania po zbudowaniu jak najmniejszego DOM strony.

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

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

  1. Podczas pierwszego renderowania strony. Zastosowanie CSS do strony powoduje utworzenie struktury podobnej do modelu DOM, znanej jako obiektowy model CSS (CSSOM). W miarę jak selektory arkusza CSS stają się bardziej szczegółowe, CSSOM staje się bardziej złożony i potrzeba więcej czasu na opracowanie niezbędnego układu, stylu, komponowania i malowania strony niezbędnej do wyświetlenia strony internetowej na ekranie. Zwiększa to czas oczekiwania na interakcje w przypadku interakcji, które mają miejsce na wczesnym etapie wczytywania strony.
  2. Gdy interakcje modyfikują DOM przez wstawianie lub usuwanie elementów lub modyfikowanie zawartości i stylów DOM, praca niezbędna do wyrenderowania tej aktualizacji może spowodować bardzo kosztowne prace nad układem, stylem, komponowaniem i malowaniem. Tak jak przy wstępnym renderowaniu strony, zwiększenie specyficzności selektora arkusza CSS może usprawnić renderowanie, gdy elementy HTML są wstawiane w elemencie DOM w wyniku interakcji.
  3. Gdy JavaScript wysyła zapytania do DOM, odwołania do elementów DOM są przechowywane w pamięci. Jeśli na przykład wywołasz funkcję document.querySelectorAll, aby wybrać wszystkie elementy <div> na stronie, koszty pamięci mogą być znaczne, jeśli w wyniku będzie widoczna duża liczba elementów DOM.
Zrzut ekranu z długim zadaniem spowodowanym nadmiernym renderowaniem w panelu wydajności Narzędzi deweloperskich w Chrome. Stos wywołań długiego zadania wykazuje znaczną ilość czasu poświęcanego na ponowne obliczanie stylów stron i wstępne renderowanie.
Długie zadanie widoczne w profilu wydajności w narzędziach deweloperskich w Chrome. Długie zadanie jest spowodowane wstawieniem elementów DOM do dużego elementu DOM za pomocą JavaScriptu.

Wszystkie te czynniki mogą wpływać na interaktywność, ale druga pozycja na liście jest szczególnie ważna. Jeśli interakcja spowoduje zmianę DOM, może to oznaczać rozpoczęcie wielu prac, które mogą przyczynić się do obniżenia wartości INP na stronie.

Jak zmierzyć rozmiar DOM?

Rozmiar DOM można mierzyć na kilka sposobów. Pierwsza metoda korzysta z Lighthouse. Po uruchomieniu kontroli statystyki dotyczące DOM bieżącej strony będą widoczne w sekcji „Unikaj nadmiernego rozmiaru DOM” pod nagłówkiem „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 najgłębszy element DOM.

Prostsza metoda wymaga użycia 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ć następującego kodu w konsoli:

document.querySelectorAll('*').length;

Jeśli chcesz obserwować zmianę rozmiaru 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 związane z wydajnością) z bieżącym rozmiarem DOM.

Zrzut ekranu przedstawiający monitor wydajności w Narzędziach deweloperskich w Chrome. Po lewej stronie dostępne są różne aspekty wydajności strony, które można stale monitorować w trakcie działania strony. Na zrzucie ekranu aktywnie monitorowana jest liczba węzłów DOM, układy na sekundę oraz ponowne obliczenia stylu na sekcję.
Monitor wydajności w Narzędziach deweloperskich w Chrome. W tym widoku na wykresie wyświetlana jest bieżąca liczba węzłów DOM strony wraz z operacjami układu i ponownymi obliczeniami stylu na sekundę.

Jeśli rozmiar DOM zbliża się do progu ostrzegawczego rozmiaru DOM w Lighthouse lub całkowicie się nie udaje, następnym krokiem jest określenie, jak zmniejszyć rozmiar DOM, aby poprawić zdolność strony do reagowania na interakcje użytkowników i poprawić wartość INP witryny.

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

Jeśli profilujesz powolną interakcję w module, który według Ciebie może mieć związek z rozmiarem DOM strony, możesz się dowiedzieć, na ile elementów DOM miało wpływ, wybierając w programie profilującym dowolne działanie o nazwie „Ponownie oblicz styl” i obserwując dane kontekstowe w dolnym panelu.

Zrzut ekranu pokazujący aktywność ponownego obliczania wybranego stylu w panelu wydajności Narzędzi deweloperskich w Chrome. U góry ścieżka interakcji przedstawia interakcję z kliknięciem, a większość pracy to proces ponownego obliczania stylu i wstępnego malowania. U dołu panelu znajduje się więcej szczegółów na temat wybranej aktywności, z której wynika, że miało to wpływ na 2547 elementów DOM.
Zaobserwowanie liczby elementów w DOM, których dotyczy zmiana w wyniku ponownego obliczania stylu. Pamiętaj, że zacieniona część interakcji na ścieżce interakcji to część czasu trwania interakcji, która trwała ponad 200 milisekund, co stanowi wyznaczony próg „dobrej” dla INP.

Na zrzucie ekranu powyżej zobacz, że przeliczenie stylu dzieła – gdy zostanie wybrane – pokazuje liczbę elementów, których dotyczy problem. Powyższy zrzut ekranu przedstawia ekstremalny wpływ rozmiaru DOM na zadania renderowania na stronie z wieloma elementami DOM. Te informacje diagnostyczne są przydatne w każdym przypadku, aby ustalić, czy rozmiar DOM jest czynnikiem ograniczającym czas potrzebny na wyrenderowanie następnej klatki w odpowiedzi na interakcję.

Jak zmniejszyć rozmiar DOM?

Oprócz kontroli kodu HTML witryny pod kątem zbędnych znaczników głównym sposobem na zmniejszenie rozmiaru DOM jest zmniejszenie głębokości DOM. Jednym z sygnałów, że DOM może być niepotrzebnie głęboki, jest to, że na karcie Elementy w narzędziach dla programistów w przeglądarce widzisz znaczniki podobne do tego:

<div>
  <div>
    <div>
      <div>
        <!-- Contents -->
      </div>
    </div>
  </div>
</div>

Jeśli zaobserwujesz takie wzorce, możesz je uprościć, spłaszczając strukturę DOM. Zmniejszy to liczbę elementów DOM, co prawdopodobnie pozwoli uprościć style stron.

Objawem używanych platform może być również Głębokość DOM. W szczególności platformy oparte na komponentach – takie jak te, które korzystają z JSX – wymagają zagnieżdżenia wielu komponentów w kontenerze nadrzędnym.

Jednak wiele platform pozwala uniknąć zagnieżdżania komponentów przez stosowanie tak zwanych fragmentów. Platformy oparte na komponentach, które oferują fragmenty jako funkcje, obejmują między innymi:

Używając fragmentów w wybranej platformie, można zmniejszyć głębokość DOM. Jeśli obawiasz się, jaki wpływ na styl ma wygładzanie struktury DOM, być może warto skorzystać z nowocześniejszych (i szybszych) trybów układu, takich jak flexbox czy grid.

Inne strategie, które warto wziąć pod uwagę

Nawet jeśli chcesz spłaszczyć drzewo DOM i usunąć zbędne elementy HTML, aby utrzymać jak najmniejszy element DOM, nadal może on być dość duży i wymagać dużej ilości pracy związanej z renderowaniem, ponieważ zmienia się on w zależności od interakcji użytkownika. Jeśli znajdziesz się w takiej sytuacji, możesz zastosować inne strategie, które pomogą Ci ograniczyć renderowanie.

Rozważ użycie addytywnego podejścia

Możesz znajdować się w sytuacji, w której duże fragmenty strony nie są początkowo widoczne dla użytkownika po pierwszym wyrenderowaniu. Może to być możliwość leniwego ładowania kodu HTML przez pomijanie tych części DOM podczas uruchamiania i dodawanie ich, gdy użytkownik wchodzi w interakcje z częściami strony, które wymagają początkowo ukrytych aspektów strony.

Ta metoda jest przydatna zarówno podczas początkowego wczytywania, jak i już po jego zakończeniu. Przy wstępnym wczytaniu strony mniej pracy musisz poświęcać na renderowanie, co oznacza, że początkowy ładunek HTML będzie mniejszy i będzie renderowany szybciej. Dzięki temu interakcje w tym kluczowym okresie będą miały więcej okazji do prowadzenia działań i będziesz mieć mniej rywalizacji o uwagę głównego wątku.

Jeśli wiele części strony jest początkowo ukrytych przy wczytywaniu, może to także przyspieszyć inne interakcje, które uruchamiają ponowne renderowanie. W miarę jak inne interakcje dodają więcej DOM, praca renderowania będzie rosła wraz z rozwojem DOM w trakcie cyklu życia strony.

Dodawanie elementu DOM w miarę upływu czasu może być trudne i ma swoje wady. Jeśli korzystasz z tej opcji, prawdopodobnie wysyłasz żądania sieciowe, aby w odpowiedzi na interakcję użytkownika pobrać dane w kodzie HTML, który chcesz dodać do strony. Choć przesyłane żądania sieciowe nie są wliczane do INP, może to zwiększyć widoczne opóźnienie. W miarę możliwości pokaż wskaźnik ładowania lub inny wskaźnik, że dane są pobierane, aby użytkownicy wiedzieli, że coś się dzieje.

Ogranicz złożoność selektora arkusza CSS

Gdy przeglądarka analizuje selektory w kodzie CSS, musi przeszukać drzewo DOM, aby dowiedzieć się, jak – i czy – mają zastosowanie do bieżącego układu. Im bardziej złożone są te selektory, tym więcej pracy musi wykonać przeglądarka, aby wykonać zarówno początkowe renderowanie strony, jak i częste ponowne obliczanie stylu i układu strony, jeśli strona zmieni się w wyniku interakcji.

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

CSS udostępnia właściwość content-visibility, która umożliwia leniwe renderowanie elementów DOM poza ekranem. Gdy elementy zbliżają się do widocznego obszaru, są renderowane na żądanie. Zalety content-visibility nie tylko eliminują znaczną ilość pracy przy pierwszym renderowaniu strony, ale także pomijają renderowanie elementów poza ekranem, gdy DOM strony zmienia się w wyniku interakcji użytkownika.

Podsumowanie

Dobrym sposobem na optymalizację wartości INP witryny jest zmniejszenie rozmiaru DOM tylko do niezbędnego minimum. Dzięki temu możesz skrócić czas potrzebny przeglądarce na zmianę układu i renderowania podczas aktualizacji DOM. Nawet jeśli nie możesz w sposób istotny zmniejszyć rozmiaru DOM, możesz stosować kilka technik, które pozwalają oddzielić renderowanie od poddrzewa DOM. Są to na przykład powłoka CSS i właściwość CSS content-visibility.

Niezależnie od tego, co się stanie, stworzenie środowiska, w którym renderowanie jest ograniczone do minimum, a jednocześnie zredukować ilość pracy związanej z renderowaniem, jaką strona wykona w odpowiedzi na interakcje – w rezultacie witryna będzie bardziej responsywna, gdy wchodzą z nią w interakcję. Oznacza to, że będziesz mieć niższy wartość INP witryny, co przełoży się na lepsze wrażenia użytkowników.

Baner powitalny z albumu Unsplash, autor: Louis Reed.