Server-side rendering

서버 사이드 렌더링

The server sends prepared HTML. The browser can show it before client-side interaction code finishes attaching.

···
html
<div class="demo"><div class="head"><strong>FIRST CONTENT</strong><span id="phase">request</span></div><div class="scene"><div class="row"><b>SSR</b><div class="track"><i id="ssr"></i></div><span id="ssrlabel">waiting</span></div><div class="row"><b>CSR</b><div class="track"><i id="csr"></i></div><span id="csrlabel">waiting</span></div></div><div class="foot"><span>HTML → JavaScript → interactive</span><span>tap to step</span></div></div>
css
.demo{width:min(92vw,660px);height:min(86vh,310px);border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(10px,2.5vmin,20px);display:flex;flex-direction:column;gap:clamp(6px,1.7vmin,12px);box-shadow:0 10px 35px rgba(0,0,0,.07);font:500 clamp(10px,2.8vmin,15px)/1.35 ui-monospace,SFMono-Regular,Consolas,monospace}
.head,.foot{display:flex;align-items:center;justify-content:space-between;gap:8px}.head strong{color:var(--accent);font-size:1.05em}.foot{color:var(--muted);font-size:.85em;min-height:1.4em}.scene{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;gap:clamp(5px,1.5vmin,12px)}.chip{border:1px solid var(--line);background:var(--bg);border-radius:7px;padding:.4em .6em;text-align:center}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 12%,var(--surface))!important;color:var(--accent)!important}.dim{opacity:.42}.arrow{color:var(--muted)}
.scene{flex-direction:column;align-items:stretch;justify-content:center}.row{display:flex;align-items:center;gap:8px;height:31%;min-height:32px}.row b{width:3em}.row span{width:6em;text-align:right}.track{flex:1;height:45%;border-radius:99px;background:var(--line);overflow:hidden}.track i{display:block;width:0;height:100%;background:var(--accent);transition:width .4s}
js
let step=0;const phases=["request","HTML arrives","JS runs","interactive"];function advance(){document.getElementById("phase").textContent=phases[step];document.getElementById("ssr").style.width=["0%","65%","85%","100%"][step];document.getElementById("csr").style.width=["0%","20%","65%","100%"][step];document.getElementById("ssrlabel").textContent=step>=1?"content":"waiting";document.getElementById("csrlabel").textContent=step>=2?"content":"waiting";step=(step+1)%4}advance();const timer=setInterval(advance,850);document.querySelector(".demo").addEventListener("pointerdown",()=>{clearInterval(timer);advance()})

With SSR, the server generates HTML for a request. The browser can display its initial content, then hydration connects interactions when the JavaScript arrives.

The demo compares simplified SSR and CSR timelines. SSR reveals content on HTML arrival; CSR reveals it after JavaScript runs. Actual performance also depends on server response and asset size.

When to use

Consider it when early content or crawlable HTML matters. Measure server cost and hydration work too.

Open as page ↗