What is hydration?
Hydration is the process where JavaScript on the client "attaches" to server-rendered HTML, turning static markup into an interactive application. After SSR (server-side rendering) sends HTML to the browser, the JS bundle downloads, parses, and re-runs the component tree to attach event handlers, restore state, and make the page interactive.
Hydration is fundamental to SSR-based frameworks (React with Next.js, Vue with Nuxt, Svelte with SvelteKit). It's also the primary cost of SSR — heavy hydration is the leading cause of poor INP (Interaction to Next Paint) on otherwise-fast pages.
The hydration sequence
- Server renders HTML and sends to browser (fast first paint)
- Browser displays HTML — page LOOKS interactive
- Browser downloads JS bundle
- JS parses + executes
- JS walks the existing DOM, matches each element to a component
- JS attaches event handlers, initializes state, restores effects
- Page is now actually interactive (hydration complete)
The user can SEE the page during steps 2-6 but clicks/taps may not work yet. That gap = the hydration cost.
Why hydration is slow
- Entire component tree re-runs. Even if 99% of components are static, JS recomputes them all to know which to attach handlers to.
- JS bundle size. Bigger tree = bigger JS = longer parse/execute.
- Synchronous on main thread. Blocks user input while running.
- Resource competition. Hydration competes with images, third-party scripts, ads.
- Cold starts on slow devices. A 200ms hydration on a fast laptop is 1-2s on a budget Android.
Modern solutions to hydration cost
| Technique | How it works | Used by |
|---|---|---|
| Partial hydration | Only hydrate components marked interactive | Astro Islands, 11ty + Petite Vue |
| Streaming SSR | Server streams HTML chunks; hydrate as they arrive | React 18+, Next.js App Router |
| Progressive hydration | Hydrate components as they enter viewport / become needed | React Server Components, Astro |
| Resumability (Qwik) | Skip hydration; serialize state + lazy-load handlers on interaction | Qwik, Qwik City |
| React Server Components (RSC) | Components run only on server; ship zero JS for them | Next.js App Router |
| Selective hydration | Hydrate the part user interacts with first; lazy-hydrate rest | React 18+ |
Hydration vs no-hydration approaches
| Approach | JS cost | Interactivity |
|---|---|---|
| SPA (CSR) | All JS upfront, no hydration | Interactive after JS loads |
| SSR + Hydration (traditional) | Full JS on every page | Visible fast, interactive after hydration |
| SSG (no JS) | Zero JS | Static — no interactivity |
| Partial Hydration (Astro Islands) | Only interactive components ship JS | Mostly static, interactive islands |
| Resumability (Qwik) | ~No JS upfront; lazy-loaded on interaction | Visible + clickable immediately |
Common hydration problems
Hydration mismatch
Server-rendered HTML differs from client-rendered output. Causes:
- Date/time formatted server-locale vs client-locale
- Random IDs different between server + client
- Browser-only APIs accessed during render (window, localStorage)
- Conditional rendering based on user-agent or viewport
React 18+ logs: Warning: Hydration failed because the initial UI does not match what was rendered on the server. This forces full client re-render — defeats SSR benefits.
Slow hydration on heavy pages
Pages with thousands of components hydrate slowly. Symptoms: bad INP, "page unresponsive" warnings.
Hydration blocking user input
User clicks button while hydration is running; click lost or queued, fires unexpectedly later.
Hydration best practices
- Minimize JS shipped. Code splitting, tree shaking, dynamic imports.
- Use partial hydration if possible. Astro Islands or React Server Components.
- Avoid SSR/CSR mismatches. Don't access browser APIs during render; use
useEffect. - Stream HTML. React 18
renderToPipeableStreamfor faster first paint. - Defer non-critical hydration. Lazy-hydrate footer, sidebar.
- Test on real devices. Hydration cost is highly device-dependent.
- Consider zero-JS for content pages. If a page has no interaction, no JS needed.
- Monitor INP in production. CrUX + RUM track real hydration impact.
Common hydration pitfalls
- Hydration mismatches in dev. Locale-sensitive content rendered both sides — must match.
- Window references during render. Throws on server. Wrap in
typeof window !== 'undefined'oruseEffect. - Random IDs. Use stable IDs or React's
useIdhook. - Heavy global state init. Restoring Redux/Zustand state during hydration blocks main thread.
- Big component trees on every route. Common navigation = repeated hydration cost.
- Third-party scripts loaded synchronously. Hurts hydration timing.
- Forgetting to test on slow devices. Hydration looks fine on dev laptop, terrible on $200 Android.
FAQ: Hydration
Why is hydration needed?
SSR sends static HTML for fast first paint. Hydration adds the JavaScript layer that makes the page actually interactive (events, state, effects).
How long should hydration take?
Aim for < 100ms on a fast device, < 300ms on a mid-tier mobile. INP target: < 200ms.
What's the difference between hydration and rendering?
Rendering: producing HTML. Hydration: attaching JS to existing HTML. Hydration follows server rendering.
What is "React hydration"?
Specifically the React process: ReactDOM.hydrateRoot() instead of ReactDOM.createRoot(). Walks server-rendered DOM and attaches React components to it.
Can I avoid hydration entirely?
For pages with no interactivity: yes (pure SSG). For interactive pages: yes via Qwik (resumability) or partial hydration (Astro Islands).
What's React Server Components?
Components that run only on the server and never ship to the client. They reduce hydration cost dramatically by sending zero JS for non-interactive parts.
Does hydration affect SEO?
Indirectly — via Core Web Vitals (INP, LCP). Slow hydration hurts INP, which Google uses as a ranking signal.
Test hydration cost with LoadFocus
LoadFocus runs Lighthouse audits from 25+ regions, measuring INP and Total Blocking Time — the metrics most affected by hydration cost. Sign up free at loadfocus.com/signup.
Related LoadFocus Tools
Put this concept into practice with LoadFocus — the same platform that powers everything you just read about.