Große DOM-Größen wirken sich stärker auf die Interaktivität aus, als Sie vielleicht denken. In diesem Leitfaden wird erläutert, warum das so ist und was Sie tun können.
Es gibt keinen Weg daran vorbei: Wenn Sie eine Webseite erstellen, hat diese ein Document Object Model (DOM). Das DOM stellt die Struktur des HTML-Codes Ihrer Seite dar und gewährt JavaScript und CSS Zugriff auf die Struktur und den Inhalt einer Seite.
Das Problem ist jedoch, dass die Größe des DOM die Fähigkeit eines Browsers beeinträchtigt, eine Seite schnell und effizient zu rendern. Generell gilt: Je größer das DOM, desto teurer ist es, die Seite zu Beginn zu rendern und das Rendering später im Seitenlebenszyklus zu aktualisieren.
Dies wird auf 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. Teure Layoutarbeiten können sich auf die Interaction to Next Paint (INP) einer Seite auswirken. Wenn Sie möchten, dass eine Seite schnell auf Nutzerinteraktionen reagiert, ist es wichtig, dass Ihre DOM-Größen nur so groß wie nötig sind.
Wann ist das DOM einer Seite zu groß?
Laut Lighthouse ist die DOM-Größe einer Seite zu groß, wenn sie 1.400 Knoten überschreitet. Lighthouse wird ab sofort Warnungen ausgeben, wenn das DOM einer Seite 800 Knoten überschreitet. Sehen wir uns zum Beispiel den folgenden HTML-Code an:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
Im obigen Code gibt es vier DOM-Elemente: das <ul>
-Element und seine drei untergeordneten <li>
-Elemente. Ihre Webseite wird mit Sicherheit viel mehr Knoten haben. Daher ist es wichtig, zu wissen, was Sie tun können, um die DOM-Größe im Auge zu behalten. Außerdem sollten Sie andere Strategien kennen, um das Rendering zu optimieren, sobald Sie das DOM einer Seite so klein wie möglich gemacht haben.
Wie wirken sich große DOMs auf die Seitenleistung aus?
Große DOMs wirken sich auf unterschiedliche Weise auf die Seitenleistung aus:
- Beim ersten Rendern der Seite. Wenn CSS auf eine Seite angewendet wird, wird eine dem DOM ähnliche Struktur namens CSS Object Model (CSSOM) erstellt. Mit zunehmender Spezifität von CSS-Selektoren wird das CSSOM immer komplexer und es wird mehr Zeit für die Ausführung der erforderlichen Layout-, Stil-, Compositing- und Paint-Arbeiten benötigt, um die Webseite auf dem Bildschirm darzustellen. Diese zusätzliche Arbeit erhöht die Interaktionslatenz für Interaktionen, die früh beim Laden der Seite erfolgen.
- Wenn Interaktionen das DOM ändern, entweder durch Einfügen oder Löschen von Elementen oder durch Ändern von DOM-Inhalten und -Styles, kann die für das Rendern dieser Aktualisierung erforderliche Arbeit sehr kostspielig sein. Wie beim anfänglichen Rendern der Seite kann eine höhere Genauigkeit des CSS-Selektors die Rendering-Leistung erhöhen, wenn HTML-Elemente als Ergebnis einer Interaktion in das DOM eingefügt werden.
- 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.
All dies kann sich auf die Interaktivität auswirken, aber der zweite Punkt in der obigen Liste ist von besonderer Bedeutung. Wenn eine Interaktion zu einer Änderung am DOM führt, kann das viel Arbeit verursachen, was zu einer schlechten INP auf einer Seite beitragen kann.
Wie messe ich die DOM-Größe?
Es gibt mehrere Möglichkeiten, die DOM-Größe zu messen. Bei der ersten Methode wird Lighthouse verwendet. Wenn Sie eine Prüfung durchführen, werden Statistiken zum DOM der aktuellen Seite im Audit „Übermäßige DOM-Größe vermeiden“ unter der Überschrift „Diagnose“ angezeigt. 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 in einem beliebigen größeren Browser. Um die Gesamtzahl der HTML-Elemente im DOM abzurufen, können Sie nach dem Laden der Seite den folgenden Code in der Konsole verwenden:
document.querySelectorAll('*').length;
Wenn Sie die Aktualisierung der 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 (und andere Leistungsaspekte) mit der aktuellen DOM-Größe in Beziehung setzen.
Wenn die DOM-Größe den Warnschwellenwert der Lighthouse-DOM-Größe erreicht oder insgesamt fehlschlägt, müssen Sie als Nächstes überlegen, wie Sie die DOM-Größe reduzieren können, um die Reaktionsfähigkeit Ihrer Seite auf Nutzerinteraktionen zu verbessern und den INP-Wert Ihrer Website zu verbessern.
Wie kann ich die Anzahl der DOM-Elemente messen, die von einer Interaktion betroffen sind?
Wenn Sie im Lab eine langsame Interaktion analysieren, die möglicherweise mit der Größe des DOM der Seite zusammenhängt, können Sie herausfinden, wie viele DOM-Elemente betroffen waren. Wählen Sie dazu im Profiler eine Aktivität mit der Bezeichnung „Stil neu berechnen“ aus und beobachten Sie die Kontextdaten im unteren Bereich.
Beachten Sie im obigen Screenshot, dass die Stil-Neuberechnung der Arbeit, sofern ausgewählt, die Anzahl der betroffenen Elemente anzeigt. Der Screenshot oben zeigt einen Extremfall der Auswirkung der DOM-Größe auf das Rendern einer Seite mit vielen DOM-Elementen. Diese Diagnoseinformationen sind jedoch in jedem Fall nützlich, um festzustellen, ob die DOM-Größe 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 zur Verringerung der DOM-Größe darin, die DOM-Tiefe zu reduzieren. Ein Hinweis darauf, dass Ihr DOM möglicherweise unnötig tief ist, ist, wenn Sie in den Entwicklertools Ihres Browsers auf dem Tab Elemente Markup sehen, das in etwa so aussieht:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Wenn Sie solche Muster sehen, können Sie sie wahrscheinlich vereinfachen, indem Sie die DOM-Struktur flach gestalten. Dadurch wird die Anzahl der DOM-Elemente reduziert und Sie haben wahrscheinlich die Möglichkeit, Seitenstile zu vereinfachen.
Die DOM-Tiefe kann auch ein Symptom der von Ihnen verwendeten Frameworks sein. Insbesondere bei komponentenbasierten Frameworks, z. B. solchen, die auf JSX basieren, müssen mehrere Komponenten in einem übergeordneten Container verschachteln werden.
Mit 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 Ihrem Framework verwenden, können Sie die DOM-Tiefe reduzieren. Wenn Sie Bedenken haben, welche Auswirkungen die vereinfachte DOM-Struktur auf die Gestaltung hat, können Sie moderne (und schnellere) Layoutmodi wie Flexbox oder Raster verwenden.
Weitere Strategien
Selbst wenn Sie sich Mühe geben, den DOM-Baum zu flach zu gestalten und unnötige HTML-Elemente zu entfernen, um das DOM so klein wie möglich zu halten, kann es immer noch ziemlich groß sein und viel Rendering-Arbeit auslösen, da es sich als Reaktion auf Nutzerinteraktionen ändert. In diesem Fall gibt es einige andere Strategien, mit denen Sie die Renderarbeit einschränken können.
Einen additiven Ansatz in Betracht ziehen
Es kann sein, dass große Teile Ihrer Seite beim ersten Rendern für den Nutzer nicht sichtbar sind. In diesem Fall könnte ein Lazy Loading für HTML genutzt werden, indem diese Teile des DOM beim Start weggelassen werden, aber hinzugefügt werden, wenn der Nutzer mit den Teilen der Seite interagiert, die die anfangs verborgenen Aspekte der Seite erfordern.
Dieser Ansatz ist sowohl beim ersten Laden als auch möglicherweise danach nützlich. Beim erstmaligen Laden der Seite entfällt das Rendering im Voraus. Das bedeutet, dass die anfängliche HTML-Nutzlast kleiner ist und schneller gerendert wird. So haben Interaktionen in dieser wichtigen Phase mehr Möglichkeiten, ausgeführt zu werden, da sie weniger um die Aufmerksamkeit des Hauptthreads konkurrieren müssen.
Wenn viele Teile der Seite beim Laden anfänglich ausgeblendet sind, können auch andere Interaktionen beschleunigt werden, die das erneute Rendern auslösen. Wenn das DOM jedoch durch andere Interaktionen erweitert wird, nimmt der Arbeitsaufwand für das Rendering zu, während das DOM während des gesamten Lebenszyklus der Seite größer wird.
Das DOM im Laufe der Zeit zu erweitern, kann schwierig sein und hat seine eigenen Vor- und Nachteile. In diesem Fall stellen Sie wahrscheinlich Netzwerkanfragen, um Daten für den HTML-Code abzurufen, den Sie als Reaktion auf eine Nutzerinteraktion der Seite hinzufügen möchten. Laufende Netzwerkanfragen werden zwar nicht auf die INP angerechnet, können aber die wahrgenommene Latenz erhöhen. Zeigen Sie nach Möglichkeit einen Ladebalken oder eine andere Anzeige, dass Daten abgerufen werden, damit Nutzer wissen, dass etwas passiert.
Komplexität von CSS-Selektoren begrenzen
Wenn der Browser Selektoren in Ihrem CSS parst, muss er die DOM-Struktur durchlaufen, um zu verstehen, wie und ob diese Selektoren auf das aktuelle Layout angewendet werden. Je komplexer diese Selektoren sind, desto mehr Arbeit muss der Browser ausführen, um sowohl das erste Rendern der Seite durchzuführen als auch den Stil und das Layout zu optimieren, falls sich die Seite infolge einer Interaktion ändert.
Das Attribut content-visibility
verwenden
CSS bietet die Eigenschaft content-visibility
, mit der sich DOM-Elemente außerhalb des Bildschirms träge rendern lassen. Wenn sich die Elemente dem Darstellungsbereich nähern, werden sie on demand gerendert. Durch die Vorteile von content-visibility
wird nicht nur der Rendering-Aufwand beim ersten Rendern der Seite reduziert, sondern auch der Rendering-Aufwand für Elemente außerhalb des sichtbaren Bereichs verringert, wenn das Seiten-DOM als Ergebnis einer Nutzerinteraktion geändert wird.
Fazit
Es ist eine gute Möglichkeit, den INP Ihrer Website zu optimieren, indem Sie Ihre DOM-Größe auf das Notwendige reduzieren. So lässt sich die Zeit verkürzen, die der Browser für das Layout und das Rendern benötigt, wenn das DOM aktualisiert wird. Auch wenn sich die DOM-Größe nicht sinnvoll reduzieren lässt, gibt es verschiedene Techniken, mit denen Sie Rendering-Arbeiten in einer DOM-Unterstruktur isolieren können, z. B. die CSS-Begrenzung und die CSS-Eigenschaft content-visibility
.
Unabhängig davon, wie Sie vorgehen, sollten Sie eine Umgebung schaffen, in der die Rendering-Arbeit minimiert wird. Außerdem sollten Sie die Menge der Rendering-Arbeit reduzieren, die Ihre Seite als Reaktion auf Interaktionen ausführt. Das Ergebnis ist, dass Ihre Website für Nutzer reaktionsschneller erscheint, wenn sie mit ihr interagieren. Das bedeutet, dass Sie einen niedrigeren INP für Ihre Website haben, was sich in einer besseren Nutzererfahrung niederschlägt.