CONCEPT Cited by 2 sources
Progressive hydration¶
Progressive hydration (sometimes partial hydration when only
some subtrees hydrate at all, or selective hydration when
priority is dynamic) is the property that a page's interactivity
is attached in pieces as each piece becomes ready, rather than
in one whole-tree pass. The classic React 17 hydrate() blocked
the main thread until every component in the tree was hydrated;
React 18's hydrateRoot + <Suspense> breaks that into
per-boundary commits that can interleave with user input.
Why it matters¶
A fully server-rendered page is visible early but isn't interactive until hydration completes. For a large tree, that gap can be seconds — long enough that a user taps a button and nothing happens, because the click handler hasn't attached yet. Progressive hydration moves the above-the-fold, visible-first regions to interactive status before the below-the-fold regions — matching the order the user is likely to engage with them.
Mechanisms¶
Three distinct stages of "progressive":
- Streaming-aligned progressive hydration — each
Suspense boundary hydrates as
its chunk arrives in the streamed response. This is the
React-18 default under
renderToPipeableStream+hydrateRoot. - Viewport-driven — hydrate only what's currently in the
viewport; delay off-screen regions until they scroll into
view. Requires framework support (e.g. Astro partial
hydration, some React frameworks with
<Suspense>+ visibility observers). - Interaction-driven (selective hydration) — when the user clicks on a not-yet-hydrated region, React reprioritises that boundary's hydration ahead of queued ones. React 18 supports this automatically.
Pre-React-18 history¶
Zalando's Rendering Engine had built partial hydration in-house before React 18 existed: "it also comes with some performance features built inside, including but not limited to streaming, lazy-loading, partial streaming and partial hydration (yes, almost the same concept as in Concurrent React!)." (Source: sources/2023-07-10-zalando-rendering-engine-tales-road-to-concurrent-react.)
Other frameworks that operationalised progressive hydration pre-React-18 include Astro, Marko, Qwik (resumability as a step further), and custom-rolled implementations at several large React sites.
The React-18 arrival makes progressive hydration a built-in capability of the mainline framework rather than a custom-maintained in-house one. Zalando's migration is partly about retiring in-house code whose function is now supported upstream.
Required invariants¶
- State injection ordering — the state that drove server
rendering of a region must be in the page before that region's
markup, or the region hydrates into a
mismatch. Confluence uses a
NodeJS
objectModetransform to enforce this (Source: sources/2026-04-16-atlassian-streaming-ssr-confluence). - Independent data resolution per boundary — each boundary's data must be resolvable without knowing any other boundary's resolution state, or progressive hydration degenerates to whole-tree-blocking hydration.
- HTML chunk-boundary preservation — every intermediate layer (compression, proxy, CDN) must be flush-friendly or the browser sees the page in one big chunk at the end. See concepts/head-of-line-buffering.
Anti-patterns¶
- Too many boundaries. Each Suspense boundary has a cost (runtime overhead, per-boundary render on shared-context changes under React 18). See concepts/react-hydration.
- A boundary per leaf component. The unit of progressive hydration should match the unit of user-visible region (nav, hero, above-fold product card grid, below-fold recs).
- Boundaries around fast content. Pure overhead; the fast content would hydrate inside its parent boundary for free.
Seen in¶
- sources/2023-07-10-zalando-rendering-engine-tales-road-to-concurrent-react — canonical wiki instance of pre-React-18 partial hydration being superseded by React-18 progressive hydration. RE's architectural fit for concurrent React hinges on its Renderers already being the right granularity to become Suspense boundaries.
- sources/2026-04-16-atlassian-streaming-ssr-confluence —
Confluence's React 18 streaming SSR with per-Suspense-boundary
hydration, state-injection-ordering discipline, and the
useContext-across-ready-boundary bug fixed in React 19.
Related¶
- concepts/react-hydration — the per-component version.
- concepts/streaming-ssr — the server-side counterpart that makes per-boundary hydration possible without regressing initial paint.
- concepts/concurrent-rendering-react — the React feature set that ships progressive hydration.
- patterns/suspense-boundary — the unit.
- systems/zalando-rendering-engine — the framework whose pre-React-18 partial-hydration implementation this concept's React-18 mainline version subsumes.