v148 · HTML · JavaScript · Declarative Partial Updates
Streaming Feed
Pipe a ReadableStream of HTML directly into a DOM element using streamHTMLUnsafe(). Content renders as chunks arrive — the same progressive parsing as the main HTML document, but for any element, at any time.
Chrome 148 flag required: This demo uses
streamHTMLUnsafe() when available
(Chrome 148+ with chrome://flags/#enable-experimental-web-platform-features).
In other browsers it falls back to a polyfill that buffers and applies on completion, so you'll
see the same result without the progressive rendering.
Hit "Stream articles" to start streaming HTML into this element
Before — innerHTML (blocks)
const res = await fetch('/api/feed.html');
const html = await res.text(); // wait for ALL bytes
// Only now can we set the content
target.innerHTML = html;
Chrome 148 — streamHTMLUnsafe
const res = await fetch('/api/feed.html');
const writer = target.streamHTMLUnsafe().getWriter();
// Or pipe directly:
res.body
.pipeThrough(new TextDecoderStream())
.pipeTo(target.streamHTMLUnsafe());
Full demo code
async function streamArticles(target, speedMs) {
// Build a ReadableStream of HTML chunks
const stream = new ReadableStream({
async start(controller) {
for (const article of ARTICLES) {
const html = renderArticle(article);
controller.enqueue(html);
await delay(speedMs);
}
controller.close();
}
});
if ('streamHTMLUnsafe' in target) {
// Chrome 148+: pipe straight in, renders progressively
await stream.pipeTo(target.streamHTMLUnsafe());
} else {
// Fallback: buffer then set
const reader = stream.getReader();
let full = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
full += value;
}
target.innerHTML = full;
}
}
see also
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗