Auswirkungen großer DOM-Größen auf die Interaktivität und mögliche Maßnahmen

Große DOM-Größen wirken sich stärker auf die Interaktivität aus, als Sie denken. In diesem Leitfaden erfahren Sie, warum das so ist und was Sie tun können.

Es geht nicht anders: Wenn Sie eine Webseite erstellen, hat diese Seite ein Document Object Model (DOM). Das DOM repräsentiert die Struktur des HTML-Codes Ihrer Seite und gewährt JavaScript- und CSS-Zugriff auf die Struktur und den Inhalt einer Seite.

Das Problem besteht jedoch darin, dass sich die Größe des DOM auf die Fähigkeit eines Browsers auswirkt, eine Seite schnell und effizient zu rendern. Generell gilt: Je größer ein DOM ist, desto teurer ist das anfängliche Rendern dieser Seite und das Aktualisieren des Renderings später im Seitenlebenszyklus.

Dies wird bei Seiten mit sehr großen DOMs problematisch, wenn Interaktionen, die das DOM ändern oder aktualisieren, teure Layoutarbeiten auslösen, die die Reaktionsfähigkeit der Seite beeinträchtigen. Kostspielige Layoutarbeiten können sich auf die Interaction to Next Paint (INP) einer Seite auswirken. Wenn eine Seite schnell auf Nutzerinteraktionen reagieren soll, ist es wichtig, dass die DOM-Größen nur so groß wie nötig sind.

Wann ist das DOM einer Seite zu groß?

Laut Lighthouse ist das DOM einer Seite zu groß, wenn sie 1.400 Knoten überschreitet. Lighthouse gibt Warnungen aus, wenn das DOM einer Seite 800 Knoten überschreitet. Nehmen wir den folgenden HTML-Beispielcode:

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

Im Code oben gibt es vier DOM-Elemente: das <ul>-Element und seine drei untergeordneten <li>-Elemente. Ihre Webseite wird höchstwahrscheinlich sehr viel mehr Knoten haben. Daher ist es wichtig zu wissen, wie Sie die DOM-Größen im Auge behalten können. Außerdem sollten Sie wissen, mit welchen anderen Strategien Sie das Rendering optimieren können, sobald das DOM einer Seite so klein wie möglich ist.

Wie wirken sich große DOMs auf die Seitenleistung aus?

Große DOMs wirken sich auf die Seitenleistung in mehreren Aspekten aus:

  1. Während des ersten Renderings der Seite Wenn CSS auf eine Seite angewendet wird, wird eine ähnliche Struktur wie das DOM erstellt, das als CSS-Objektmodell (CSSOM) bezeichnet wird. Je spezifischer die CSS-Selektoren sind, desto komplexer wird das CSSOM. Außerdem wird mehr Zeit benötigt, um das erforderliche Layout, die Gestaltung, den Aufbau und die Farbpalette auszuführen, um die Webseite auf den Bildschirm zu zeichnen. Dieser zusätzliche Aufwand erhöht die Interaktionslatenz für Interaktionen, die früh beim Seitenaufbau stattfinden.
  2. Wenn Interaktionen das DOM ändern, entweder durch Einfügen oder Löschen von Elementen oder durch Ändern von DOM-Inhalten und -Stilen, kann die zum Rendern dieser Aktualisierung erforderliche Arbeit zu kostspieligen Layout-, Gestaltungs-, Compositing- und Paint-Arbeiten führen. Wie beim ersten Rendering der Seite kann eine höhere Spezifität des CSS-Selektors die Rendering-Arbeit verbessern, wenn HTML-Elemente als Ergebnis einer Interaktion in das DOM eingefügt werden.
  3. Wenn JavaScript das DOM abfragt, werden Verweise auf DOM-Elemente im Arbeitsspeicher gespeichert. Wenn Sie beispielsweise document.querySelectorAll aufrufen, um alle <div>-Elemente auf einer Seite auszuwählen, können die Speicherkosten beträchtlich sein, wenn das Ergebnis eine große Anzahl von DOM-Elementen zurückgibt.
Screenshot einer langen Aufgabe, die durch übermäßiges Rendering im Leistungsbereich der Chrome-Entwicklertools verursacht wurde. Der Aufrufstack der Long-Aufgabe zeigt viel Zeit, die für die Neuberechnung von Seitenstilen und für das Vorabmalen aufgewendet wurde.
Eine lange Aufgabe, wie sie im Leistungsprofil-Profil in den Chrome-Entwicklertools angezeigt wird. Die angezeigte Task „Long“ wird durch das Einfügen von DOM-Elementen in ein großes DOM über JavaScript verursacht.

All dies kann die Interaktivität beeinflussen, aber der zweite Punkt in der Liste oben ist von besonderer Bedeutung. Wenn eine Interaktion zu einer Änderung des DOM führt, kann dies eine Menge Arbeit bedeuten, die zu einer schlechten INP auf einer Seite führen kann.

Wie messe ich die DOM-Größe?

Sie können die DOM-Größe auf verschiedene Arten messen. Bei der ersten Methode wird Lighthouse verwendet. Wenn Sie eine Prüfung ausführen, werden Statistiken zum DOM der aktuellen Seite in der Prüfung „Übermäßige DOM-Größe vermeiden“ unter der Überschrift „Diagnose“ aufgeführt. In diesem Abschnitt sehen Sie die Gesamtzahl der DOM-Elemente – das DOM-Element mit den meisten untergeordneten Elementen sowie das tiefste DOM-Element.

Eine einfachere Methode ist die Verwendung der JavaScript-Konsole in den Entwicklertools eines gängigen Browsers. Um die Gesamtzahl der HTML-Elemente im DOM zu erhalten, können Sie den folgenden Code in der Konsole verwenden, nachdem die Seite geladen wurde:

document.querySelectorAll('*').length;

Wenn Sie die aktualisierte DOM-Größe in Echtzeit sehen möchten, können Sie auch die Leistungsüberwachung verwenden. Mit diesem Tool können Sie Layout- und Stilvorgänge sowie andere Leistungsaspekte mit der aktuellen DOM-Größe in Beziehung setzen.

Screenshot der Leistungsüberwachung in den Chrome-Entwicklertools Links sind verschiedene Aspekte der Seitenleistung verfügbar, die während der gesamten Laufzeit der Seite kontinuierlich überwacht werden können. Im Screenshot werden die Anzahl der DOM-Knoten, Layouts pro Sekunde und Stilneuberechnungen pro Abschnitt aktiv überwacht.
Die Leistungsüberwachung in den Chrome-Entwicklertools. In dieser Ansicht werden die aktuelle Anzahl der DOM-Knoten auf der Seite sowie Layoutvorgänge und Stilneuberechnungen pro Sekunde grafisch dargestellt.

Wenn die Größe des DOMs den Warnschwellenwert des Lighthouse-DOMs fast erreicht oder sogar komplett ausfällt, sollten Sie als Nächstes herausfinden, wie Sie die Größe des DOMs reduzieren können, damit Ihre Seite besser auf Nutzerinteraktionen reagieren und die INP Ihrer Website verbessert werden kann.

Wie kann ich die Anzahl der DOM-Elemente messen, die von einer Interaktion betroffen sind?

Wenn Sie im Lab ein Profil für eine langsame Interaktion erstellen, von der Sie vermuten, dass sie etwas mit der Größe des DOM der Seite zu tun haben, können Sie herausfinden, wie viele DOM-Elemente durch die Auswahl einer Aktivität im Profiler mit der Bezeichnung "Stil neu berechnen" betroffen waren. Beobachten Sie dann die Kontextdaten im unteren Bereich.

Screenshot mit ausgewählten Aktivitäten zur Neuberechnung von Stilen im Bereich „Leistung“ der Chrome-Entwicklertools. Oben im Interaktions-Track ist eine Klickinteraktion zu sehen. Der Großteil der Arbeit wird für die Stilneuberechnung und Voranstriche aufgewendet. Unten in einem Steuerfeld werden weitere Details zur ausgewählten Aktivität angezeigt, aus denen hervorgeht, dass 2.547 DOM-Elemente betroffen waren.
Beobachten der Anzahl der Elemente im DOM, die durch eine Neuberechnung von Stilen betroffen sind. Der schattierte Teil der Interaktion im Interaktions-Track stellt den Teil der Interaktionsdauer dar, der über 200 Millisekunden lag. Dies ist der bestimmte Grenzwert für „gut“ für INP.

Im obigen Screenshot sehen Sie, dass die Stil-Neuberechnung des Werks – sofern ausgewählt – die Anzahl der betroffenen Elemente zeigt. Der Screenshot oben zeigt einen Extremfall der Auswirkungen der DOM-Größe auf das Rendering einer Seite mit vielen DOM-Elementen. Diese Diagnoseinformationen sind jedoch in jedem Fall nützlich, um festzustellen, ob die Größe des DOM ein einschränkender Faktor dafür ist, wie lange es dauert, bis der nächste Frame als Reaktion auf eine Interaktion dargestellt wird.

Wie kann ich die DOM-Größe reduzieren?

Neben der Prüfung des HTML-Codes Ihrer Website auf unnötiges Markup besteht die Hauptmethode zum Reduzieren der DOM-Größe darin, die DOM-Tiefe zu reduzieren. Ein Signal dafür, dass Ihr DOM unnötig tief sein könnte, ist, wenn Sie auf dem Tab Elemente der Entwicklertools Ihres Browsers ein Markup sehen, das in etwa so aussieht:

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

Wenn Sie Muster wie diese sehen, können Sie diese wahrscheinlich vereinfachen, indem Sie Ihre DOM-Struktur vereinfachen. Dadurch wird die Anzahl der DOM-Elemente reduziert und wahrscheinlich können Sie Seitenstile vereinfachen.

Die DOM-Tiefe kann auch ein Symptom der verwendeten Frameworks sein. Insbesondere bei komponentenbasierten Frameworks, wie solchen, die auf JSX basieren, müssen mehrere Komponenten in einem übergeordneten Container verschachtelt werden.

Bei vielen Frameworks können Sie jedoch das Verschachteln von Komponenten vermeiden, indem Sie sogenannte Fragmente verwenden. Zu den komponentenbasierten Frameworks, die Fragmente als Funktion anbieten, gehören unter anderem:

Wenn Sie Fragmente in einem Framework Ihrer Wahl verwenden, können Sie die DOM-Tiefe reduzieren. Wenn Sie Bedenken bezüglich der Auswirkungen der Vereinfachung der DOM-Struktur auf die Stile haben, könnten modernere (und schnellere) Layoutmodi wie Flexbox oder Raster von Vorteil sein.

Weitere mögliche Strategien

Selbst wenn Sie Ihren DOM-Baum flach darstellen und unnötige HTML-Elemente entfernen, um das DOM so klein wie möglich zu halten, kann es dennoch recht groß sein und viel Rendering-Arbeit erfordern, da es sich in Reaktion auf Nutzerinteraktionen ändert. Wenn Sie sich in dieser Position befinden, gibt es einige andere Strategien, die Sie in Betracht ziehen können, um die Rendering-Arbeit einzuschränken.

Additiven Ansatz erwägen

Eventuell sind große Teile Ihrer Seite beim ersten Rendern für den Nutzer nicht sichtbar. Dies könnte eine Gelegenheit sein, HTML mithilfe von Lazy Loading zu laden, indem diese Teile des DOM beim Start ausgelassen werden, aber hinzugefügt werden, wenn der Nutzer mit den Teilen der Seite interagiert, die die ursprünglich verborgenen Aspekte der Seite erfordern.

Dieser Ansatz ist sowohl während des anfänglichen Ladevorgangs als auch möglicherweise auch danach nützlich. Beim ersten Laden der Seite benötigen Sie im Vorfeld weniger Rendering-Aufwand. Das bedeutet, dass die anfängliche HTML-Nutzlast leichter ist und schneller gerendert wird. So erhalten Interaktionen in diesem entscheidenden Zeitraum mehr Gelegenheiten, und weniger Konkurrenz um die Aufmerksamkeit des Hauptthreads.

Wenn viele Teile der Seite beim Laden anfangs ausgeblendet sind, können dadurch auch andere Interaktionen beschleunigt werden, die das erneute Rendern auslösen. Je mehr Interaktionen das DOM jedoch umfasst, desto höher ist der Rendering-Aufwand, wenn das DOM während des gesamten Seitenlebenszyklus wächst.

Das Hinzufügen des DOMs im Laufe der Zeit kann schwierig sein und hat auch Nachteile. In diesem Fall senden Sie wahrscheinlich Netzwerkanfragen, um Daten in den HTML-Code einzufügen, den Sie der Seite als Reaktion auf eine Nutzerinteraktion hinzufügen möchten. Laufende Netzwerkanfragen werden zwar nicht für INP gezählt, können aber die wahrgenommene Latenz erhöhen. Zeigen Sie nach Möglichkeit ein Ladesymbol oder einen anderen Indikator dafür, dass Daten abgerufen werden, damit Nutzer verstehen, dass etwas passiert.

Komplexität des CSS-Selektors begrenzen

Wenn der Browser Selektoren in Ihrem CSS analysiert, muss er den DOM-Baum durchlaufen, um festzustellen, wie und ob sich diese Selektoren auf das aktuelle Layout auswirken. Je komplexer diese Selektoren sind, desto mehr muss der Browser erledigen, um sowohl das ursprüngliche Rendern der Seite als auch vermehrte Stil-Neuberechnungen und Layoutänderungen durchzuführen, falls sich die Seite infolge einer Interaktion ändert.

content-visibility-Property verwenden

CSS bietet die Eigenschaft content-visibility, mit der DOM-Elemente außerhalb des Bildschirms verzögert gerendert werden können. Sobald sich die Elemente dem Darstellungsbereich nähern, werden sie bei Bedarf gerendert. Durch die Vorteile von content-visibility wird nicht nur ein erheblicher Teil des Renderingprozesses beim ersten Rendern der Seite reduziert, sondern auch das Rendering von Elementen außerhalb des Bildschirms übersprungen, wenn das Seiten-DOM infolge einer Nutzerinteraktion geändert wird.

Fazit

Wenn Sie die INP-Größe Ihrer Website optimieren möchten, sollten Sie die DOM-Größe auf das unbedingt notwendige Maß reduzieren. Auf diese Weise lässt sich die Zeit reduzieren, die der Browser benötigt, um Layout- und Rendering-Aufgaben auszuführen, wenn das DOM aktualisiert wird. Auch wenn sich die DOM-Größe nicht sinnvoll reduzieren lässt, können Sie mit einigen Techniken die Rendering-Arbeit in eine DOM-Unterstruktur isolieren, z. B. die CSS-Begrenzung und die CSS-Eigenschaft content-visibility.

Ganz gleich, wie Sie dabei vorgehen, Sie sollten eine Umgebung schaffen, in der das Rendering auf ein Minimum reduziert wird. Und nicht nur der Aufwand für das Rendern Ihrer Seite als Reaktion auf Interaktionen, wird im Endergebnis dazu führen, dass Ihre Website bei der Interaktion mit den Nutzenden reaktionsschneller wirkt. Das bedeutet, dass der INP für Ihre Website niedriger ist, was wiederum zu einer besseren Nutzererfahrung führt.

Hero-Image aus Unsplash von Louis Reed