Lesson 75 of 80
Classic server rendering waits for the slowest piece of data before sending a single byte. Streaming sends the shell first and patches in the slow parts as they finish.
14 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Classic server-side rendering builds the entire HTML string for a page, top to bottom, before sending anything to the browser. If one part of the page needs a slow database query, the whole response waits on it — a fast product title sits blocked behind a slow reviews list that hasn't loaded yet.
Streaming SSR breaks that dependency. You wrap the slow part in a Suspense boundary, and React sends the rest of the page — the "shell" — the instant it's ready, with a fallback placeholder sitting where the slow part will go. When the slow data resolves, React streams a small chunk of HTML and script that swaps the placeholder for the real content, in place, without the browser reloading anything.
import { renderToPipeableStream } from "react-dom/server";
function ProductPage() {
return (
<Layout>
<ProductSummary /> {/* fast — part of the shell */}
<Suspense fallback={<ReviewsSkeleton />}>
<Reviews /> {/* slow — streamed in later */}
</Suspense>
</Layout>
);
}
renderToPipeableStream(<ProductPage />, {
onShellReady() {
response.statusCode = 200;
response.setHeader("Content-Type", "text/html");
pipe(response);
},
});
onShellReady fires the moment everything outside a Suspense boundary is done rendering — ProductSummary and ReviewsSkeleton, not Reviews itself. The browser gets real, paintable HTML immediately and starts rendering the page while Reviews is still fetching on the server. Once that fetch resolves, React finishes rendering Reviews in the background and streams the result down the same connection as an out-of-order chunk; a small inline script relocates it into the skeleton's spot. No second request, no client-side refetch — the server just kept the connection open and sent more.
getServerSideProps-style model where one slow call blocked the whole response, including parts that had nothing to do with it.This is the same Suspense component this track's lazy-loading lesson uses to pause rendering for a component that isn't ready yet — streaming SSR is that identical mechanism applied on the server instead of the client, deciding what to send now versus later instead of what to render now versus later. What arrives from the server still has to become interactive the same way any server-rendered markup does, which is this track's hydration lesson.