PATTERN Cited by 2 sources
Suspense Boundary (progressive rendering)¶
A Suspense boundary is a declarative "this subtree may not be ready
yet" marker placed in a component tree. The renderer commits everything
outside the boundary immediately, replaces the inside with a fallback
(loading placeholder), and resumes rendering the subtree — and emitting
its markup — when its dependencies resolve. In React 18,
<Suspense fallback={...}> is the concrete API; combined with
renderToPipeableStream it becomes the unit of streaming SSR.
Server-side emission shape (React 18)¶
Pending boundary in initial HTML:
When the boundary's data resolves, React streams its completed markup
as a later chunk plus inline JS that replaces the <template> by ID
and transitions the marker comment to <!--$-->. The browser paints
the update in place.
Design properties¶
- Failure granularity: a slow dependency on one boundary doesn't block paint of everything else. Placement of boundaries is a deliberate design choice — navigation + chrome above, content body below; fast content above, slow charts below.
- Hydration granularity: each boundary hydrates independently as its chunk arrives, so interactivity is incremental.
- Fallback is a design surface: placeholders should not cause layout shift (CLS), and should approximate the final bounding box.
Coupling with data loaders¶
Boundaries are only useful if data fetching is split to match. Confluence added a granular preloading implementation that mirrors the component tree, letting each preload feed exactly one boundary (Source: sources/2026-04-16-atlassian-streaming-ssr-confluence). Without this, the whole page waits on the slowest loader and streaming degenerates to classic SSR.
Anti-patterns¶
- Too many boundaries: each adds hydration/runtime overhead, and in React 18 each additional ready boundary costs one extra render pass across any shared subtree touched by a context change. See concepts/react-hydration.
- Boundaries around fast, co-located content: pure overhead.
- Boundaries that forget state injection: the state that drove server rendering must arrive before the boundary's markup or hydration mismatches.
Seen in¶
- sources/2026-04-16-atlassian-streaming-ssr-confluence —
<Suspense>boundaries as the streaming unit in Confluence's SSR pipeline, paired with a component-tree-aligned data preloader. - sources/2023-07-10-zalando-rendering-engine-tales-road-to-concurrent-react
— canonical wiki instance of Renderer-as-Suspense-boundary in
an entity-based page-composition framework. Zalando's
Rendering Engine wraps every Renderer in
<Suspense>as part of the React 18 migration. Unlike Confluence's hook-based data loader, Zalando drives boundary suspension from an Application- State layer outside React via a Connector hook that either returns data or throws a Promise. Also surfaces known React-18 Suspense gotchas:SuspenseListis experimental with limitations anduseTransitiondoesn't consider nested Suspense boundaries — both named as reasons not to lean purely on hook-based render-as-you-fetch.