Das Rendern von HTML mit JavaScript unterscheidet sich vom Rendern von HTML, das vom Server gesendet wird. Das kann sich auf die Leistung auswirken. In diesem Leitfaden erfahren Sie mehr über die Unterschiede und was Sie tun können, um die Rendering-Leistung Ihrer Website zu verbessern, insbesondere bei Interaktionen.
Das Parsen und Rendern von HTML ist etwas, das Browser standardmäßig sehr gut für Websites erledigen, die die integrierte Navigationslogik des Browsers verwenden – manchmal auch als „traditionelle Seitenaufrufe“ oder „Hard Navigations“ bezeichnet. Solche Websites werden auch als Multi-Page-Anwendungen (MPAs) bezeichnet.
Entwickler können jedoch Browserstandardeinstellungen umgehen, um sie an die Anforderungen ihrer Anwendung anzupassen. Das ist sicherlich bei Websites der Fall, die das Single-Page-Anwendungs-Muster (SPA) verwenden, bei dem große Teile des HTML/DOM dynamisch auf dem Client mit JavaScript erstellt werden. Dieses Designmuster wird als clientseitiges Rendering bezeichnet und kann sich auf die Interaction to Next Paint (INP) Ihrer Website auswirken, wenn der damit verbundene Aufwand zu hoch ist.
In diesem Leitfaden erfahren Sie, wie Sie die Unterschiede zwischen der Verwendung von HTML, das vom Server an den Browser gesendet wird, und der Erstellung von HTML auf dem Client mit JavaScript abwägen können. Außerdem wird erläutert, wie letzteres zu einer hohen Interaktionslatenz in entscheidenden Momenten führen kann.
So rendert der Browser vom Server bereitgestelltes HTML
Beim Navigationsmuster, das bei herkömmlichen Seitenladevorgängen verwendet wird, wird bei jeder Navigation HTML vom Server empfangen. Wenn Sie eine URL in die Adressleiste Ihres Browsers eingeben oder auf einen Link in einer MPA klicken, passiert Folgendes:
- Der Browser sendet eine Navigationsanfrage für die angegebene URL.
- Der Server antwortet mit HTML in Chunks.
Der letzte Schritt ist entscheidend. Es ist auch eine der grundlegendsten Leistungsoptimierungen beim Austausch zwischen Server und Browser und wird als Streaming bezeichnet. Wenn der Server so schnell wie möglich mit dem Senden von HTML beginnen kann und der Browser nicht auf die gesamte Antwort warten muss, kann der Browser HTML in Blöcken verarbeiten, sobald es eintrifft.

Wie die meisten Vorgänge im Browser erfolgt das Parsen von HTML innerhalb von Aufgaben. Wenn HTML vom Server an den Browser gestreamt wird, optimiert der Browser das Parsen dieses HTML-Codes, indem er dies nach und nach vornimmt, wenn Teile des Streams in Blöcken eintreffen. Die Folge ist, dass der Browser den Hauptthread nach der Verarbeitung jedes Chunks regelmäßig unterbricht, wodurch lange Aufgaben vermieden werden. Das bedeutet, dass andere Aufgaben ausgeführt werden können, während HTML geparst wird. Dazu gehören das inkrementelle Rendern, das erforderlich ist, um eine Seite dem Nutzer zu präsentieren, sowie die Verarbeitung von Nutzerinteraktionen, die während der wichtigen Startphase der Seite auftreten können. Dieser Ansatz führt zu einem besseren INP-Wert (Interaction to Next Paint) für die Seite.
Das bedeutet: Wenn Sie HTML vom Server streamen, erhalten Sie inkrementelles Parsen und Rendern von HTML und automatisches Yielding an den Hauptthread kostenlos. Beim clientseitigen Rendering ist das nicht der Fall.
So rendert der Browser HTML, das von JavaScript bereitgestellt wird
Jede Navigationsanfrage an eine Seite erfordert, dass der Server eine gewisse Menge an HTML-Code bereitstellt. Einige Websites verwenden jedoch das SPA-Muster. Bei diesem Ansatz wird vom Server oft eine minimale anfängliche Nutzlast von HTML bereitgestellt. Der Client füllt dann den Hauptinhaltsbereich einer Seite mit HTML, das aus vom Server abgerufenen Daten zusammengestellt wird. Nachfolgende Navigationsvorgänge, die in diesem Fall manchmal als „Soft Navigations“ bezeichnet werden, werden vollständig von JavaScript übernommen, um die Seite mit neuem HTML zu füllen.
Clientseitiges Rendering kann auch in Nicht-SPAs in begrenzteren Fällen auftreten, in denen HTML dynamisch über JavaScript in das DOM eingefügt wird.
Es gibt einige gängige Methoden zum Erstellen von HTML oder zum Hinzufügen von HTML zum DOM über JavaScript:
- Mit der
innerHTML
-Eigenschaft können Sie den Inhalt eines vorhandenen Elements über einen String festlegen, den der Browser in DOM parst. - Mit der
document.createElement
-Methode können Sie neue Elemente erstellen, die dem DOM hinzugefügt werden sollen, ohne dass der Browser HTML parsen muss. - Mit der Methode
document.write
können Sie HTML in das Dokument schreiben. Der Browser parst es wie bei Ansatz 1. Aus verschiedenen Gründen wird jedoch von der Verwendung vondocument.write
dringend abgeraten.

Die Folgen der Erstellung von HTML/DOM über clientseitiges JavaScript können erheblich sein:
- Im Gegensatz zu HTML, das vom Server als Reaktion auf eine Navigationsanfrage gestreamt wird, werden JavaScript-Aufgaben auf dem Client nicht automatisch in Chunks aufgeteilt. Dies kann zu langen Aufgaben führen, die den Hauptthread blockieren. Das bedeutet, dass sich die INP Ihrer Seite negativ auswirken kann, wenn Sie zu viel HTML/DOM gleichzeitig auf dem Client erstellen.
- Wenn HTML beim Start auf dem Client erstellt wird, werden darin referenzierte Ressourcen nicht vom Browser-Preload-Scanner erkannt. Dies wirkt sich mit Sicherheit negativ auf den Largest Contentful Paint (LCP) einer Seite aus. Dies ist zwar kein Problem mit der Laufzeitleistung, sondern ein Problem mit der Netzwerkverzögerung beim Abrufen wichtiger Ressourcen. Sie sollten jedoch vermeiden, dass der LCP Ihrer Website durch die Umgehung dieser grundlegenden Browserleistungsoptimierung beeinträchtigt wird.
Was kann ich tun, um die Leistung bei clientseitigem Rendern zu verbessern?
Wenn Ihre Website stark auf clientseitiges Rendering angewiesen ist und Sie schlechte INP-Werte in Ihren Felddaten beobachtet haben, fragen Sie sich möglicherweise, ob das clientseitige Rendering etwas mit dem Problem zu tun hat. Wenn Ihre Website beispielsweise eine SPA ist, können Sie anhand der Felddaten Interaktionen ermitteln, die für einen erheblichen Rendering-Aufwand verantwortlich sind.
Was auch immer die Ursache ist, hier sind einige mögliche Gründe, die Sie untersuchen können, um die Situation wieder in den Griff zu bekommen.
So viel HTML wie möglich vom Server bereitstellen
Wie bereits erwähnt, verarbeitet der Browser HTML vom Server standardmäßig sehr effizient. Dadurch werden das Parsen und Rendern von HTML so aufgeteilt, dass lange Aufgaben vermieden und die Gesamtzeit des Hauptthreads optimiert wird. Dies führt zu einer niedrigeren Total Blocking Time (TBT). Die TBT ist stark mit INP korreliert.
Möglicherweise verwenden Sie ein Frontend-Framework, um Ihre Website zu erstellen. Wenn ja, sollten Sie darauf achten, dass Sie das HTML der Komponente auf dem Server rendern. Dadurch wird die Menge des anfänglichen clientseitigen Renderings, das für Ihre Website erforderlich ist, begrenzt und die Nutzerfreundlichkeit sollte sich verbessern.
- Für React sollten Sie die Server DOM API verwenden, um HTML auf dem Server zu rendern. Die herkömmliche Methode des serverseitigen Renderings verwendet jedoch einen synchronen Ansatz, der zu einer längeren Zeit bis zum ersten Byte (Time to First Byte, TTFB) sowie zu nachfolgenden Messwerten wie First Contentful Paint (FCP) und LCP führen kann. Verwenden Sie nach Möglichkeit die Streaming-APIs für Node.js oder andere JavaScript-Laufzeitumgebungen, damit der Server so schnell wie möglich mit dem Streamen von HTML an den Browser beginnen kann. Next.js, ein auf React basierendes Framework, bietet standardmäßig viele Best Practices. Neben dem automatischen Rendern von HTML auf dem Server kann auch statisches HTML für Seiten generiert werden, die sich nicht basierend auf dem Nutzerkontext (z. B. Authentifizierung) ändern.
- Vue führt standardmäßig auch clientseitiges Rendering durch. Wie bei React kann Vue jedoch auch die HTML-Komponente auf dem Server rendern. Nutzen Sie diese serverseitigen APIs nach Möglichkeit oder erwägen Sie eine Abstraktion auf höherer Ebene für Ihr Vue-Projekt, um die Best Practices einfacher zu implementieren.
- Svelte rendert HTML standardmäßig auf dem Server. Wenn Ihr Komponentencode jedoch auf browserbezogene Namespaces (z. B.
window
) zugreifen muss, können Sie das HTML der Komponente möglicherweise nicht auf dem Server rendern. Versuchen Sie, unnötiges clientseitiges Rendern zu vermeiden. SvelteKit – das für Svelte dasselbe ist wie Next.js für React – bettet so viele Best Practices wie möglich in Ihre Svelte-Projekte ein, damit Sie potenzielle Fallstricke in Projekten vermeiden können, die nur Svelte verwenden.
Anzahl der auf dem Client erstellten DOM-Knoten begrenzen
Wenn DOMs groß sind, steigt in der Regel der Aufwand, der für das Rendern erforderlich ist. Unabhängig davon, ob Ihre Website eine vollwertige SPA ist oder bei einer MPA als Ergebnis einer Interaktion neue Knoten in ein vorhandenes DOM eingefügt werden, sollten Sie diese DOMs so klein wie möglich halten. Dadurch wird der Arbeitsaufwand beim clientseitigen Rendern zum Anzeigen dieses HTML-Codes reduziert, was hoffentlich dazu beiträgt, dass der INP-Wert Ihrer Website niedriger bleibt.
Streamingdienst-Worker-Architektur in Betracht ziehen
Das ist eine fortgeschrittene Technik, die nicht für jeden Anwendungsfall geeignet ist. Sie kann jedoch dazu führen, dass sich Ihre MPA wie eine Website anfühlt, die sofort geladen wird, wenn Nutzer von einer Seite zur nächsten wechseln. Mit einem Service Worker können Sie die statischen Teile Ihrer Website im CacheStorage
vorab im Cache speichern und mit der ReadableStream
API den Rest des HTML-Codes einer Seite vom Server abrufen.
Wenn Sie diese Technik erfolgreich einsetzen, wird kein HTML auf dem Client erstellt. Das sofortige Laden von Inhalts-Partials aus dem Cache erweckt jedoch den Eindruck, dass Ihre Website schnell geladen wird. Websites, die diesen Ansatz verwenden, können sich fast wie eine SPA anfühlen, aber ohne die Nachteile des clientseitigen Renderings. Außerdem wird die Menge an HTML-Code reduziert, die Sie vom Server anfordern.
Kurz gesagt: Eine Streaming-Service-Worker-Architektur ersetzt nicht die integrierte Navigationslogik des Browsers, sondern ergänzt sie. Weitere Informationen dazu, wie Sie dies mit Workbox erreichen können, finden Sie unter Schnellere mehrseitige Anwendungen mit Streams.
Fazit
Wie Ihre Website HTML empfängt und rendert, hat Auswirkungen auf die Leistung. Wenn Sie sich darauf verlassen, dass der Server das gesamte (oder den Großteil des) für die Funktion Ihrer Website erforderliche HTML sendet, erhalten Sie viel kostenlos: inkrementelles Parsen und Rendern sowie automatisches Yielding an den Hauptthread, um lange Aufgaben zu vermeiden.
Das clientseitige HTML-Rendering birgt eine Reihe potenzieller Leistungsprobleme, die in vielen Fällen vermieden werden können. Aufgrund der Anforderungen der einzelnen Websites lässt sich das jedoch nicht immer vermeiden. Um potenzielle lange Aufgaben zu vermeiden, die durch übermäßiges clientseitiges Rendern entstehen können, sollten Sie möglichst viel HTML Ihrer Website vom Server senden. Halten Sie die DOM-Größen für HTML, das auf dem Client gerendert werden muss, so klein wie möglich. Erwägen Sie außerdem alternative Architekturen, um die Bereitstellung von HTML an den Client zu beschleunigen und gleichzeitig die inkrementelle Analyse und das Rendern zu nutzen, die der Browser für HTML bietet, das vom Server geladen wird.
Wenn Sie das clientseitige Rendering Ihrer Website so gering wie möglich halten, verbessern Sie nicht nur den INP-Wert Ihrer Website, sondern auch andere Messwerte wie LCP, TBT und in einigen Fällen sogar TTFB.
Hero-Image von Unsplash, von Maik Jonietz.