Question presented to candidate: "Streaming SSR is supposed to mean a slow section does not hold up the page. Walk me through what actually goes over the wire."
What a strong answer should cover:
- Instead of building the whole document then sending it, the server sends the shell immediately and streams each Suspense boundary's content as its data resolves.
- The initial chunk contains the shell plus each boundary's fallback. Later chunks carry the real content plus a tiny inline script that swaps it into place.
- Chunks can arrive out of order — a fast section overtakes a slow one, and React reorders on the client. That is why it is not just "flush as you go".
- Selective hydration: React hydrates boundaries independently as their HTML arrives, rather than requiring the whole page. The page becomes interactive in pieces.
- It prioritises the boundary the user interacted with — clicking an unhydrated region makes React hydrate that one first.
- The API is
renderToPipeableStream(Node) orrenderToReadableStream(web runtimes);renderToStringis blocking and does not support Suspense at all. onShellReadyis the moment to start sending;onAllReadyis for crawlers or static generation, where you want the complete document.- The benefit is time-to-first-byte and first paint decoupled from your slowest query.
Clarifying questions expected:
- "Node or an edge runtime?" — that decides which API.
- "Do we need the full HTML for a crawler?" — that is
onAllReadyrather thanonShellReady.
Code / implementation expected: Optional. Naming the right renderer and where the boundaries go is the substance.