Streaming SSR

스트리밍 서버 렌더링

The server sends ready HTML chunks before the entire page is finished.

···
html
<section class="stage"><div class="heading">STREAMING <span class="hint">chunks arrive separately</span></div><div class="stream"><div class="pipeline"><span class="chunk">header</span><span class="chunk">article</span><span class="chunk">comments</span></div><div class="arrow">→</div><div class="rendered"><div class="piece">HEADER</div><div class="piece">ARTICLE</div><div class="piece">COMMENTS</div></div></div><div class="caption">The browser paints each available chunk</div></section>
css
.stage{width:min(94vw,780px);height:min(88vh,322px);padding:clamp(12px,3vmin,20px);border:1px solid var(--line);border-radius:16px;background:var(--surface);box-shadow:0 12px 36px #0001;display:flex;flex-direction:column;gap:clamp(7px,2vmin,14px);font:500 clamp(12px,3.5vmin,17px)/1.3 var(--font-sans,system-ui,sans-serif);overflow:hidden}.heading{display:flex;justify-content:space-between;align-items:center;gap:8px;font-weight:750;color:var(--accent)}.hint{color:var(--muted);font-size:clamp(12px,3.2vmin,14px);font-weight:500}.caption{margin-top:auto;color:var(--muted);font-size:clamp(12px,3.2vmin,14px)}.row{display:flex;gap:clamp(5px,1.5vmin,12px);align-items:center}.tile{padding:clamp(6px,1.8vmin,13px);border:1px solid var(--line);border-radius:9px;background:var(--bg);text-align:center;min-width:0}.arrow{color:var(--accent);font-weight:800}.stage [data-on]{transition:background .3s,border-color .3s,opacity .3s,transform .3s}.stage .on{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,var(--surface));color:var(--accent)}.stream{flex:1;display:flex;align-items:center;justify-content:center;gap:clamp(6px,2vmin,20px)}.pipeline{display:flex;flex-direction:column;gap:7px}.chunk{padding:6px 9px;border:1px solid var(--accent-2);border-radius:7px;color:var(--accent-2);opacity:.25;transition:opacity .3s,transform .3s}.rendered{width:45%;max-width:240px;border:1px solid var(--line);border-radius:9px;padding:8px;display:flex;flex-direction:column;gap:6px}.piece{height:28px;border:1px dashed var(--line);border-radius:6px;display:grid;place-items:center;color:var(--muted);opacity:.3;transition:opacity .3s,background .3s}.stage[data-step="0"] .chunk:first-child,.stage[data-step="1"] .chunk:nth-child(-n+2),.stage[data-step="2"] .chunk,.stage[data-step="0"] .piece:first-child,.stage[data-step="1"] .piece:nth-child(-n+2),.stage[data-step="2"] .piece{opacity:1;background:color-mix(in srgb,var(--accent) 12%,var(--surface));color:var(--fg)}.stage small,.stage button,.stage .cards b,.stage .phase b,.stage .pair b,.stage .tree-mini b{font-size:clamp(12px,3.2vmin,14px)!important}
js
const stage=document.querySelector(".stage");let step=0;function tick(){stage.dataset.step=String(step);step=(step+1)%3}tick();let timer=setInterval(tick,970);stage.addEventListener("pointerdown",()=>{clearInterval(timer);tick()})

Streaming SSR sends a response in HTML chunks. A ready header or article can appear while a slow section is still being prepared.

Chunk boundaries and loading states help users understand progressive completion. Streaming does not make a slow data source faster by itself.

When to use

Use it when some page regions are ready sooner than slower data-driven regions.

Open as page ↗