"매 server 가 render 한 static HTML 에 client JS 가 event handler / state 를 부여하는 과정". 매 SSR 의 SEO + first paint 이점 + SPA 의 interactivity 의 결합. 2026 시점 매 trend 는 매 less hydration — Astro Islands, React Server Components, Qwik resumability 가 매 full-page hydration 을 대체.
매 핵심
매 단계
Server: render to HTML string (renderToString / renderToPipeableStream).
Client: HTML parsing → first paint (TTFB / FCP).
Hydration: JS download → React/framework 가 component tree 의 event listener attach + state restore.
Interactive: TTI 도달.
매 cost
매 download + parse + execute JS — 매 모바일 mid-tier 에서 무거움.
Hydration mismatch — 매 server vs client output 차이 시 warning + re-render.
매 unused interactivity 도 매 hydrate (Wasted hydration).
매 modern alternatives
Selective / progressive hydration (React 18+): Suspense 단위로 lazy hydrate.
Islands architecture (Astro, Fresh): 매 interactive island 만 ship + hydrate.
Resumability (Qwik): hydration 자체 제거 — 매 server 에서 serialize 한 closure 를 매 event 시점에 lazy resume.
React Server Components: 매 server-only component 는 ship X — 매 client component 만 hydrate.
<Suspensefallback={<Skeleton/>}><HeavyChart/>{/* 매 이 boundary 만 lazy hydrate */}</Suspense>
Astro Islands
---
import Counter from "../components/Counter.svelte";
---
<h1>Static</h1>
<Counter client:visible /> {/* 매 viewport 진입 시 hydrate */}
Qwik resumability
import{component$,useSignal}from"@builder.io/qwik";exportdefaultcomponent$(()=>{constc=useSignal(0);// 매 click 전에는 JS 미실행 — 매 lazy resume
return<buttononClick$={()=>c.value++}>{c.value}</button>;});
Avoiding hydration mismatch
// 매 client-only value (Date.now, window) 는 useEffect 에서
functionNow() {const[t,setT]=useState<string|null>(null);useEffect(()=>setT(newDate().toISOString()),[]);return<span>{t??""}</span>;// 매 server: empty, client: 실제값
}
React Server Components (Next.js)
// app/page.tsx — server component, 매 hydrate X
exportdefaultasyncfunctionPage() {constdata=awaitdb.posts.findMany();return<ClientWidgetdata={data}/>;// 매 ClientWidget 만 hydrate
}