Quick reference · Print-friendly

Hydration diagnosis field guide

Trace identity first, then scheduling, then payload cost.

3 questionsSame tree? · Ready code? · Right boundary?

Trace the lifecycle

StageWhat existsWhat can failEvidence
Server renderHTML snapshot + serialized inputsNondeterminism, leaked personalization, slow dataResponse HTML, server spans, TTFB
Browser paintDOM and native browser behaviorLayout shift, misleading controls, blocked resourcesFilmstrip, LCP, resource waterfall
Code startupDownloaded and evaluated modulesLarge bundles, long tasks, dependency waterfallsCoverage, CPU profile, TBT/INP
HydrationClient tree matched to existing DOMMismatch, stale snapshot, boundary suspensionRecoverable errors, component stack, traces
InteractiveManaged state, events, effects, subscriptionsQueued intent, lost clicks, slow updatesInteraction traces, field INP, task success

Mismatch checklist

Time and randomness

Dates, counters, UUIDs, random ordering, and expiring state differ across executions.

Environment branches

Rendering on window, storage, viewport, media queries, or feature detection changes the tree.

Data races

The client reads fresher data instead of hydrating from the serialized server snapshot.

Markup correction

Invalid nesting causes the browser parser to repair HTML before the runtime matches it.

Locale and timezone

Formatting depends on defaults that are not identical across server and browser.

DOM mutation

Extensions, scripts, personalization, or A/B tools modify nodes before hydration.

Repair in this order

  1. Capture the exact mismatch and component stack through development warnings or onRecoverableError.
  2. Compare the server HTML with the client’s first render—not with the eventual post-effect UI.
  3. Serialize every input that shapes initial markup and initialize the client from that snapshot.
  4. Move unavoidable browser-only differences after hydration or use the same stable placeholder.
  5. Place Suspense boundaries around independently loadable, useful regions—not around arbitrary component sizes.
  6. Reduce shipped code and work. Selective hydration prioritizes cost; it does not delete cost.
  7. Use suppression only for an unavoidable leaf whose mismatch cannot affect structure or behavior.

Interview phrases worth earning

“Visible is not equivalent to interactive; I would inspect the gap between paint, code availability, and boundary hydration.”

“The client should hydrate from the server snapshot, then converge on fresher state.”

“Streaming and selective hydration share Suspense boundaries, but one schedules HTML delivery and the other schedules client activation.”

“Boundary placement should follow independent user intent, latency, and failure—not the component-file tree.”