Hydration in Depth — Cheat Sheet

FE Lead prep · ref 10 · §2.2 · paying down SSR's client-side bill

The frame — hydration is SSR's bill

Server HTML is dead (no listeners). Hydration makes it alive. Every strategy = one move: hydrate LATER · hydrate LESS · hydrate NEVER.

What hydration does

  1. Download the whole JS bundle.
  2. Re-execute every component (rebuild tree in memory — work the server already did).
  3. Walk DOM + attach listeners & state to existing server HTML.

Why it's expensive

Cruel irony: SSR helps slow devices paint sooner, but slow devices pay most to hydrate (CPU-bound). "SSR + hydrate everything" = fast FCP, can lose INP vs lean CSR.

The cures (later / less / never)

LeverStrategyWhat
LATERlazy / selective / progressivedefer hydration to idle / on-visible / on-interaction; React selective = per-<Suspense>, prioritises clicked
LESSislandsstatic HTML sea + isolated interactive islands; most of page ships 0 JS
LESSpartial hydration (RSC)server components ship 0 JS; only "use client" subtrees hydrate
NEVERresumability (Qwik)serialize state+listeners into HTML; resume on click, no replay

Islands — the model + directives

Sea of static server HTML with small islands of interactivity, each hydrating independently on its own trigger. Static by default, interactive by exception (Jason Miller).
<Header />                       // static — 0 JS
<SearchBox  client:load />        // hydrate now (above fold)
<Carousel   client:visible />     // hydrate on scroll-in
<Newsletter client:idle />        // hydrate when main thread idle
Islands vs RSC: same goal (less JS), diff axis. Islands = where interactivity lives on the page (independent mini-apps, framework-agnostic). RSC = where a component renders (server vs "use client") in one React tree + streaming + server data. Increasingly combined.

Resumability — "hydrate never"

Hydration (React/Vue)Resumability (Qwik)
On loaddownload + re-execute tree + attach all listenersattach ~1 global listener; nothing else
Scales withapp size — O(n)~constant — O(1)
Startup JSwhole bundle~0 (loads on 1st interaction)
Headline: hydration startup cost grows with app size; resumability stays flat. Big app + cheap phone = where it wins.

Platform angle

Lead one-liners (memorize)

Frame  "Hydration is the bill SSR hands you on the client. Every strategy is one move: hydrate later, less, or never."
Cost  "It re-runs the whole app on the client just to attach handlers — eager, all-at-once, main thread. Fast paint, but the slow phone pays twice."
Islands  "Islands flip the default: static by default, interactive by exception — each island hydrates on its own trigger, most of the page ships no JS."
Resume  "Hydration's startup cost grows with the app; resumability's is flat — Qwik serializes listeners into the HTML and resumes on click instead of replaying."

Sources: web.dev — Rendering on the Web · patterns.dev — Islands · patterns.dev — Progressive Hydration · Jason Miller — Islands · Astro — Islands · Qwik — Resumable

Don't fail the interview

1. Hydration = make server HTML interactive (download JS → re-run components → attach listeners). NOT compression, NOT server data-fetch.
2. Expensive because eager + all-at-once + main-thread + re-does server work + double data → top INP cost.
3. Slow devices pay most for hydration (CPU-bound) — the cruel irony of SSR.
4. Lazy/progressive/islands still HYDRATE (less/later). Only resumability skips hydration entirely.
5. Resumability scaling: hydration O(n) in app size, resumability O(1). Not a server-time or zero-bytes claim.
6. Islands ≠ RSC (where interactivity lives vs where a component renders). Islands ≠ micro-frontends.
7. Match trigger to element: client:load primary/above-fold, client:visible below. Never reverse.
8. "Migrate everything to Qwik" / "Qwik is a toy" = both junior. Answer is conditional + evidence-led.