Veröffentlicht: 19. Mai 2026
Das Web hat sich längst von dem statischen, dokumentbasierten Medium entfernt, als das es begann. Moderne, umfangreiche Web-Apps werden von allen aus vielen Gründen verwendet, z. B. zur Kommunikation, zum Kauf und Konsum von Rich Content und zur Verwaltung unseres komplexen Lebens.
HTML wird trotz aller Fortschritte immer noch von oben nach unten ausgeliefert, ohne Rücksicht darauf, wann Inhalte bereit sind oder wann der Nutzer sie aufruft. Mit CSS können Sie die Reihenfolge von Inhalten ändern, was jedoch oft erhebliche Auswirkungen auf die Barrierefreiheit hat. Mit JavaScript können Sie das DOM über verschiedene APIs bearbeiten, um sich etwas von dieser Einschränkung zu befreien. Dazu ist jedoch häufig eine ausführliche Syntax oder die Erstellung von DOM-Bäumen erforderlich, die in HTML eingefügt werden müssen.
Die Leistung ist für das Web von entscheidender Bedeutung, da es sich um ein Client-Server-Medium handelt. Oft werden jedoch suboptimale Entscheidungen getroffen, um die Reihenfolge von HTML zu umgehen, was die Leistung verlangsamt. Dazu gehört, zu warten, bis die gesamte Seite bereit ist, oder ein umfangreiches Framework zu verwenden, um Komponenten asynchron bereitzustellen. Die Beliebtheit von JavaScript-Frameworks zeigt, dass Webentwickler ein komponentenbasiertes Modell dem starren Dokumentmodell der Web-Ursprünge vorziehen.
Das Chrome-Team hat sich mit diesem Problem befasst und unter dem Namen Declarative Partial Updates (Deklarative partielle Updates) neue Ergänzungen für die Webplattform entwickelt.
Zwei neue API-Sets erleichtern die Bereitstellung von HTML in einer weniger linearen Weise, entweder in beliebiger Reihenfolge im HTML-Dokument selbst oder durch einfachere Möglichkeiten, HTML dynamisch in bestehende Dokumente einzufügen, indem neue JavaScript-APIs verwendet werden. Sie können ab Chrome 148 mit dem Flag chrome://flags/#enable-experimental-web-platform-features von Entwicklern getestet werden. Es sind auch Polyfills verfügbar, mit denen Sie diese neuen APIs sofort verwenden können, auch in Browsern, die sie noch nicht unterstützen.
Diese Ergänzungen der Webplattform werden standardisiert und haben positives Feedback von anderen Browseranbietern und Standardisierungsorganisationen erhalten. Die entsprechenden Standards werden derzeit aktualisiert, um diese neuen APIs zu berücksichtigen.
Streaming in beliebiger Reihenfolge
Die erste Gruppe von Änderungen sind neue Streaming-APIs für die Verarbeitung von Daten in beliebiger Reihenfolge, die das HTML-Element <template> und Platzhalter für Verarbeitungsanweisungen verwenden. Beispiel:
<div>
<?marker name="placeholder">
</div>
...
<template for="placeholder">
Here is some <em>HTML content</em>!
</template>
Verarbeitungsanweisungen gibt es in XML schon lange, in HTML wurden sie jedoch als Kommentare behandelt und ignoriert. Die neue API ändert das und führt Verarbeitungsanweisungen in HTML ein. Wenn der Browser die <?marker name="placeholder">-Verarbeitungsanweisungen sieht, passiert erst einmal nichts – wie zuvor auch. Sie können aber später referenziert werden.
Das <template>-Element sucht mit einem name-Attribut nach den entsprechenden Verarbeitungsanweisungen und ersetzt den Inhalt. In diesem Fall sieht das DOM nach dem Parsen so aus:
<div>
Here is some <em>HTML content</em>!
</div>
Neben dem Attribut <?marker> für Ersetzungen gibt es auch die Bereichsmarkierungen <?start> und <?end>, mit denen temporäre Platzhalterinhalte angezeigt werden können, bevor die Vorlage verarbeitet wird:
<div>
<?start name="another-placeholder">
Loading…
<?end>
</div>
...
<template for="another-placeholder">
Here is some <em>HTML content</em>!
</template>
In diesem Fall wird Loading… angezeigt, bis <template> zu sehen ist. Dann wird Loading… durch den neuen Inhalt ersetzt.
Es ist auch möglich, Verarbeitungsanweisungen in Vorlagen einzufügen, um mehrere Aktualisierungen zu ermöglichen:
<ul id="results">
<?start name="results">
Loading…
<?end>
</ul>
...
<template for="results">
<li>Result One</li>
<?marker name="results">
</template>
...
<template for="results">
<li>Result Two</li>
<?marker name="results">
</template>
...
Nach dem Parsen ergibt sich folgender HTML-Code:
<ul id="results">
<li>Result One</li>
<li>Result Two</li>
<?marker name="results">
</ul>
Mit der endgültigen Verarbeitungsanweisung am Ende für den Fall, dass dem Dokument später weitere <template for="results"> hinzugefügt werden.
Demo
In diesem Video wird eine einfache Fotoalbumanwendung mit Streaming-HTML implementiert:
Sowohl der Status als auch die Fotos werden nach dem ersten Layout in das HTML gestreamt.
Anwendungsfälle
Es gibt viele Anwendungsfälle für dieses HTML-Patching in beliebiger Reihenfolge in Kombination mit Streaming-HTML:
- Inselarchitektur: Ein gängiges Muster, das durch Frameworks wie Astro bekannt wurde, ist die Inselarchitektur, bei der Komponenten unabhängig voneinander auf statischem HTML gerendert werden. Mit der
<template for>API können statische Inhalte direkt in HTML auf ähnliche Weise verarbeitet werden. JavaScript-Frameworks können dies auch für interaktivere Islands oder zum Verarbeiten von Komponenten verwenden. - Inhalte bereitstellen, sobald sie fertig sind. Dank dieser Inselarchitektur können Inhalte gestreamt werden, sobald sie bereit sind, anstatt auf Inhalte zu warten, die eine zusätzliche Verarbeitung erfordern, z. B. eine Datenbanksuche. Viele Plattformen ermöglichen zwar das Streamen von HTML, aber die sequenzielle Natur von HTML führt dazu, dass Inhalte oft zurückgehalten werden oder komplexe JavaScript-DOM-Manipulationen erforderlich sind. Sie können nun die statischen Inhalte ausliefern, während Sie warten, und dann die teureren Inhalte am Ende des HTML-Streams einfügen.
- HTML kann in der optimalen Reihenfolge für die Seitenaufbauleistung bereitgestellt werden. Sie können die Bestellung auch noch ändern, wenn sie bereits abgeschlossen ist. Megamenüs sind beispielsweise ein häufiges Navigationsfeature, das viel HTML enthält, das der Nutzer erst sieht, wenn die Seite interaktiv wird. Dieser große HTML-Abschnitt kann später im HTML-Dokument bereitgestellt werden, um wichtigeres HTML zu priorisieren, das für den ersten Seitenaufbau erforderlich ist. HTML ist keine Barriere mehr.
Das sind nur einige Anwendungsfälle. Wir sind gespannt, wofür Entwickler diese neue API verwenden.
Einschränkungen und Besonderheiten
Für die API gelten einige Einschränkungen und Besonderheiten, die Sie beachten sollten:
- Aus Sicherheitsgründen kann
<template for>Verarbeitungsanweisungen nur innerhalb desselben übergeordneten Elements aktualisieren. Wenn Sie<template for>direkt dem<body>-Element hinzufügen, hat es Zugriff auf das gesamte Dokument (einschließlich des<head>). - Die
<?end>-Verarbeitungsanweisung ist optional. Wenn sie fehlt, wird der Inhalt zwischen dem<?start>-Element und dem Ende des enthaltenden Elements ersetzt. - Wenn Sie Verarbeitungsanweisungen verschieben, nachdem ein
<template for>mit dem Streaming begonnen hat, kann das unerwartete Folgen haben, da die neuen Inhalte weiterhin an den alten Speicherort gestreamt werden. - Beachten Sie, dass beim dynamischen Einfügen von
<template for>mit einer Methode wiesetHTMLoderinnerHTMLdas „übergeordnete Element“ der Vorlage beim Parsen ein Zwischenfragment des Dokuments ist. Das bedeutet, dass durch das Einfügen von HTML mit diesen Methoden kein vorhandenes DOM geändert werden kann. Das Patchen erfolgt „in place“ innerhalb des Fragments. Beim Streaming mit Methoden wiestreamHTMLUnsafe(die wir gleich behandeln) gibt es jedoch kein Zwischenfragment, sodass die Vorlagen vorhandene Inhalte ersetzen können.
Mögliche zukünftige Ergänzungen
Folgende potenzielle Ergänzungen werden derzeit in Betracht gezogen:
- Clientseitige Includes: Beispiel:
<template for="footer" patchsrc="/partials/footer.html">. - Batching: Clientseitig könnten Fragment-Includes auch erweitert werden, um Batching zu ermöglichen, damit mehrere Aktualisierungen gleichzeitig erfolgen.
- Überschreiben von Inhalten verhindern, die sich nicht ändern: Dies könnte durch eine Inhaltsrevisionsnummer oder Versionsverwaltung erreicht werden. So kann der Status zwischen Routenänderungen oder anderen Aktualisierungen beibehalten werden, anstatt den Inhalt zurückzusetzen.
- Bereinigen beim Patchen: z. B.
<template for=icon safe><svg id="from-untrusted-source">...</svg></template>.
Polyfill
Das Chrome-Team hat eine template-for-polyfill auf npm veröffentlicht, damit Websites diese neue Funktion sofort nutzen können, noch bevor sie in anderen Browsern verfügbar ist.
Es gibt einige Einschränkungen, da die HTML-Parser des Browsers nicht direkt aktualisiert werden können. Die gängigsten Anwendungsfälle werden jedoch abgedeckt. Websites sollten weiterhin in anderen Browsern getestet werden.
Erneuerte HTML-Einfüge- und Streamingmethoden
Nicht alle Inhalte können in HTML bereitgestellt werden. Ein zweiter Teil der Arbeit, die Chrome in diesem Bereich leistet, besteht darin, das Aktualisieren von Inhalten über JavaScript zu vereinfachen.
Es gibt bereits mehrere Möglichkeiten, HTML mithilfe von JavaScript dynamisch in ein vorhandenes Dokument einzufügen:
setHTMLsetHTMLUnsafeinnerHTML- undouterHTML-SettercreateContextualFragmentinsertAdjacentHTML
Sie funktionieren jedoch alle etwas anders und es gibt Feinheiten und Unterschiede, die Entwickler möglicherweise nicht immer berücksichtigen:
- Werden die neuen Inhalte überschrieben oder angehängt?
- Wird potenziell gefährlicher HTML-Code bereinigt, indem z. B.
<script>-Tags maskiert werden? - Wenn nicht, sollte
<script>ausgeführt werden? - Wie funktionieren sie mit Trusted Types?
Nur wenige Entwickler konnten sich diese APIs ansehen und die Fragen für jede von ihnen mit Zuversicht beantworten.
Eine große Einschränkung besteht darin, dass sie nur für einen vollständigen Satz von HTML-Code verwendet werden können, der im Voraus bekannt ist, wenn Aufrufe erfolgt sind, um HTML-Streaming zu ermöglichen. In der Praxis bedeutet das, dass Sie die gesamten Inhalte herunterladen müssen, bevor Sie sie einfügen können. Einer der großen Vorteile von HTML ist jedoch, dass Inhalte sofort gestreamt werden können. Dies lässt sich nur begrenzt umgehen, indem Sie Nutzlasten aufteilen oder veraltete Methoden wie document.write verwenden, was jedoch eigene Probleme mit sich bringt.
Neue APIs für statische und Streaming-Daten
Chrome hat eine Reihe neuer APIs und Erweiterungen für die vorhandenen setHTML und setHTMLUnsafe vorgeschlagen, die dies bereinigen und Streamingfunktionen einführen:
Es gibt Methoden zum Festlegen oder Ersetzen sowie zum Einfügen von Inhalten vor oder nach vorhandenem HTML-Code. Für jede Methode gibt es Stream-Entsprechungen:
| Aktion | Statisch | Streaming |
|---|---|---|
| HTML-Inhalte des Elements festlegen | setHTML(html, options); |
streamHTML(options); |
| Ersetzen Sie das gesamte Element durch diesen HTML-Code. | replaceWithHTML(html, options); |
streamReplaceWithHTML(options); |
| HTML vor dem Element einfügen | beforeHTML(html, options); |
streamBeforeHTML(options); |
| Fügen Sie den HTML-Code als erstes untergeordnetes Element des Elements hinzu. | prependHTML(html, options); |
streamPrependHTML(options); |
| Fügen Sie den HTML-Code als letztes untergeordnetes Element des Elements hinzu. | appendHTML(html, options); |
streamAppendHTML(options); |
| HTML nach dem Element einfügen | afterHTML(html, options); |
streamAfterHTML(options); |
Es gibt auch Unsafe-Versionen, die wir uns gleich ansehen. Auch wenn es viele davon gibt (insbesondere, wenn Sie die Unsafe-Entsprechungen hinzufügen), macht die einheitliche Namenskonvention deutlicher, was die einzelnen Methoden bewirken, als bei den zuvor erwähnten, nicht verwandten Methoden.
Die statischen Versionen akzeptieren neues HTML als DOM-String-Argument sowie optionale Optionen:
const newHTML = "<p>This is a new paragraph</p>";
const contentElement = document.querySelector('#content-to-update');
contentElement.setHTML(newHTML);
Die Streaming-Versionen funktionieren mit der Streams API, z. B. mit einem getWriter():
const contentElement = document.querySelector('#content-to-update');
const writer = contentElement.streamHTMLUnsafe().getWriter();
// Example stream of updating content
while (true) {
await writer.write(`<p>${++i}</p>`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
writer.close();
Alternativ können Sie sie auch aus einer Fetch-Antwort mit Pipe-Chains abrufen:
const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');
response.body
.pipeThrough(new TextDecoderStream())
.pipeTo(contentElement.streamHTMLUnsafe());
Wir planen außerdem, eine Convenience-Methode hinzuzufügen, mit der Sie direkt streamen können, ohne den Zwischenschritt TextDecoderStream() zu benötigen.
Mit dem Argument options können Sie eine benutzerdefinierte sanitizer angeben, die standardmäßig auf default festgelegt ist, d. h. die Standardkonfiguration für die Bereinigung. So wird sie verwendet:
const newHTML = "<p>This is a new paragraph</p>";
const contentElement = document.querySelector('#content-to-update');
// Only allows basic formatting
const basicFormattingSanitzer = new Sanitizer({ elements: ["em", "i", "b", "strong"] });
contentElement.setHTML(newHTML, {sanitizer: basicFormattingSanitzer});
„Unsichere“ Methoden
Es gibt auch „unsichere“ Versionen der einzelnen APIs:
| Aktion | Statisch | Streaming |
|---|---|---|
| HTML-Inhalte des Elements festlegen | setHTMLUnsafe(html,options); |
streamHTMLUnsafe(options); |
| Ersetzen Sie das gesamte Element durch diesen HTML-Code. | replaceWithHTMLUnsafe(html, options); |
streamReplaceWithHTMLUnsafe(options); |
| HTML vor dem Element einfügen | beforeHTMLUnsafe(html, options); |
streamBeforeHTMLUnsafe(options); |
| Fügen Sie den HTML-Code als erstes untergeordnetes Element des Elements hinzu. | prependHTMLUnsafe(html, options); |
streamPrependHTMLUnsafe(options); |
| Fügen Sie den HTML-Code als letztes untergeordnetes Element des Elements hinzu. | appendHTMLUnsafe(html, options); |
streamAppendHTMLUnsafe(options); |
| HTML nach dem Element einfügen | afterHTMLUnsafe(html, options); |
streamAfterHTMLUnsafe(options); |
Bei diesen „unsicheren“ Methoden wird der Sanitizer standardmäßig deaktiviert (Sie können bei Bedarf einen benutzerdefinierten Sanitizer angeben). Außerdem können Skripts mit der optionalen runScripts-Option ausgeführt werden (Standardwert: false).
Wie setHTML ist setHTMLUnsafe eine vorhandene Methode. Der Parameter runScripts wurde jedoch hinzugefügt, damit die Methode für die Skriptausführung verwendet werden kann:
const newHTML = `<p>This is a new paragraph</p>
<script src=script.js></script>`;
const contentElement = document.querySelector('#content-to-update');
contentElement.setHTMLUnsafe(newHTML, {runScripts: true});
Die Formulierung „unsicher“ in der Methode soll Entwickler an das potenzielle Risiko erinnern und daran, dass sie Skripts bereinigen oder einschränken sollten. Sie bedeutet nicht, dass diese Methoden nicht verwendet werden sollten.
Wie „unsicher“ das ist, hängt davon ab, wie vertrauenswürdig die Eingaben sind. Die statischen Unsafe-Methoden funktionieren alle sowohl mit DOM-Strings als auch mit TrustedHTML als html-Argumente und ermöglichen auch die Verwendung von Sanitizern. Bei runScript ist es jedoch das Ziel, Scripts zuzulassen. Daher wird standardmäßig kein Sanitizer verwendet.
Anwendungsfälle
Mit diesen neuen APIs können Entwickler einfacher HTML zu vorhandenen Seiten hinzufügen. Außerdem werden neue APIs mit einheitlichen Namen und Optionen eingeführt. Die Streaming-APIs bieten den Leistungsvorteil, dass nicht gewartet werden muss, bis alle neuen Inhalte auf der Plattform verfügbar sind.
Dies ist unter anderem in folgenden Fällen hilfreich:
- Dynamisches Streaming großer Content-Updates in Single-Page-Anwendungen Wie bereits erwähnt, war ein großer Nachteil aktueller SPAs, dass sie nicht vom Streaming der ersten HTML-Ladevorgänge profitieren konnten – bis jetzt.
- Häufig verwendete Inhalte wie HTML-Fußzeilen einfügen: Mit den JavaScript-APIs können Sie Partials abrufen und in die Seite einfügen. Dabei profitieren Sie vom Caching, anstatt sie auf jeder gesendeten Seite zu wiederholen. Da jedoch JavaScript für die Ausführung erforderlich ist, sollte diese Methode nur für Inhalte verwendet werden, die beim ersten Laden nicht sichtbar sind.
Das sind nur einige Beispiele. Wir sind gespannt, was ihr euch einfallen lasst.
Einschränkungen und Besonderheiten
Für diese neuen APIs gelten einige Einschränkungen und Besonderheiten, die Sie beachten sollten:
- Für die Integration von Streaming mit der Trusted Types API ist die Verwendung einer neuen
createParserOptions-Methode erforderlich, mit der ein Sanitizer in jeden HTML-Einstellungsvorgang eingefügt werden kann. Weitere Informationen zur Integration vertrauenswürdiger Typen - Ähnlich wie bei
<template for>können durch das Verschieben von Elementen, in die gestreamt wird, unerwartete Folgen oder Streamingfehler auftreten. streamHTMLUnsafefunktioniert in vielerlei Hinsicht ähnlich wie der Hauptparser, z. B. werden<template for>-Anweisungen verarbeitet, sobald sie dem Hauptdokument hinzugefügt werden, unddefer-Scripts werden bis zum Ende des Streams aufgeschoben.
Polyfill
Das Chrome-Team hat eine html-setters-polyfill auf npm veröffentlicht, damit Websites diese neue Funktion sofort nutzen können, noch bevor sie in anderen Browsern verfügbar ist.
Dieser Polyfill streamt nicht, sondern puffert und wird angewendet, wenn er vollständig ist. Es handelt sich eher um ein Polyfill für die API-Form als für die Funktionalität.
Außerdem hängt die Festlegung von sicheren Inhalten von setHTML und der Sanitizer API ab, die in Safari nicht unterstützt wird.
Beide zusammen verwenden
Das sind zwar zwei separate APIs, aber ihr volles Potenzial entfaltet sich erst, wenn sie kombiniert werden. Durch das Streamen neuer <template for>-Elemente in den HTML-Code können Sie verschiedene Inhaltsteile dynamisch aktualisieren, ohne sie mit separaten JavaScript-Verweisen auf das DOM direkt ansprechen zu müssen.
Ein einfacher Seitenaufruf im SPA-Stil könnte so implementiert werden, dass eine Übersichtsseite mit Verarbeitungsanweisungen geladen und dann die Vorlagen jeder neuen Seite in den unteren Bereich des HTML-Codes gestreamt werden, um in diese Verarbeitungsanweisungen eingefügt zu werden.
Es gibt zweifellos noch mehr Potenzial und Anwendungsfälle für diese beiden APIs. Lassen Sie sich also nicht von unserer (begrenzten!) Fantasie einschränken. Durch die einfachere Verwaltung von Teilaktualisierungen können Sie Boilerplate-Code reduzieren, Aktualisierungen vereinfachen und neue Möglichkeiten für das Web erschließen.