Skip to content

CONCEPT Cited by 2 sources

React Hydration

Hydration is the process by which a frontend React runtime takes over server-rendered HTML: it walks the existing DOM, verifies the markup matches what it would render locally, and attaches event handlers / effects to make the page interactive — without recreating the DOM nodes. It replaced earlier SSR approaches that threw the server HTML away and re-rendered client-side, which was slower and caused visible jank.

Invariants

  • Markup identity: server and client must produce the same HTML for the initial state. Divergence forces a full re-render (client-side rendering fallback), regressing both TTVC and TTI and showing up as low hydration success rate in metrics.
  • State availability at hydration time: whatever state drove server rendering must be present in the page before the client hydrates that subtree.

Interaction with streaming SSR

Under concepts/streaming-ssr, hydration happens per <Suspense> boundary as each boundary's chunk arrives. The state driving that boundary's render must be injected before the boundary's markup, not after — or hydration mismatches and the subtree re-renders on the client. Confluence's pipeline uses a NodeJS transform in objectMode that buffers emitted state while React is mid-chunk, then flushes data before markup on setImmediate (Source: sources/2026-04-16-atlassian-streaming-ssr-confluence).

Known pitfall: context change across a ready Suspense boundary

(React 18)

If a React Context value changes during hydration, React 18 discards and re-renders the component subtree — and under streaming SSR, it does this once per Suspense boundary as each becomes ready. TTI regresses proportionally to boundary count. Worked around with unstable_scheduleHydration (raise hydration priority to keep context stable); confirmed fixed in React 19. (Source: sources/2026-04-16-atlassian-streaming-ssr-confluence)

A leaky state-management library compounded this because discarded renders didn't clean up event listeners — permanent CPU growth. General lesson: rollouts measured only on topline metrics miss secondary-guardrail regressions; track CPU, hydration success rate, and per-boundary render counts.

Seen in

  • sources/2026-04-16-atlassian-streaming-ssr-confluence — React 18 hydration in Confluence's streaming SSR pipeline.
  • sources/2023-07-10-zalando-rendering-engine-tales-road-to-concurrent-reactcanonical wiki instance of production-scale hydration-mismatch fixing. Zalando's Rendering Engine migration to React 18 / hydrateRoot surfaced mismatches across "hundreds of Renderers" in the Fashion Store codebase. Also names the key debugger-friendly functions in the React dev bundle (checkForUnmatchedText, throwOnHydrationMismatch) and establishes the four-category concepts/hydration-mismatch taxonomy (timers, timezone, number-locale incl. Safari de-AT Intl.NumberFormat bug, invalid HTML nesting). Narrow API-swap A/B test: INP −5.69 % / FID −8.81 % vs React-17's hydrate.
  • hydration as a monitoring blind spot. A 2024 Zalando incident: new headless-CMS content broke the front-end API-gateway contract and crashed React hydration on "eagerly-hydrated" parts of product detail pages, breaking size-selection and add-to-cart. React error boundaries "weren't working for the eagerly-hydrated part of our product pages"; the failure slipped past CI (which doesn't see live CMS content), past service-level alerts (HTTP 200 still flowed), and past trace-derived CBO error- rate alerts (no error tag on the trace). The remediation was a new monitoring tier — a Playwright e2e test probe on a 30-minute cron — that runs a real browser through a real user journey and catches interactivity failures the rest of the stack misses. Canonical wiki evidence that hydration failures are a distinct monitoring gap requiring browser-altitude probes.
Last updated · 542 distilled / 1,571 read