Suggest an editImprove this articleRefine the answer for “What is streaming SSR and how does it work?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Streaming SSR** is an approach where, instead of waiting for the whole render to finish, the server **streams finished parts of the HTML as they become ready**. **Key point:** the user sees the interface skeleton within milliseconds, and content loads in gradually, without a "blank loading screen".Shown above the full answer for quick recall.Answer (EN)Image## The problem with classic SSR With regular (blocking) SSR, the server: 1. Collects all the data (fetch / database). 2. Renders the **entire React component** into a string (`renderToString`). 3. **Only after that** sends the finished HTML to the user. The user sees the page **only after the whole render is done** - even if part of the content could have been displayed earlier. --- ## What Streaming SSR does **Streaming SSR** solves this problem: instead of waiting for the whole render to finish, the server **streams finished parts of the HTML as they become ready**. ### How it works: 1. The server starts rendering the React component. 2. As soon as part of the tree (for example, `<Header>` or `<Skeleton>`) is ready - the server **immediately sends it into the stream**. 3. The browser **paints** these fragments instantly. 4. The remaining pieces arrive gradually (for example, when the promises for data resolve). 5. After the JS loads, **hydration** runs - the page becomes interactive. --- ## Example in React 18 ### Server ```javascript import { renderToPipeableStream } from "react-dom/server"; import express from "express"; import App from "./App"; const app = express(); app.get("/", (req, res) => { let didError = false; const stream = renderToPipeableStream(<App />, { onShellReady() { res.status(didError ? 500 : 200); res.setHeader("Content-Type", "text/html"); stream.pipe(res); // HTML starts to flow }, onError(err) { didError = true; console.error(err); }, }); }); ``` ### Client ```javascript import { hydrateRoot } from "react-dom/client"; hydrateRoot(document.getElementById("root"), <App />); ``` > `renderToPipeableStream()` is the streaming version of `renderToString()`, > which lets React send HTML in chunks as they become ready. --- ## Advantages of Streaming SSR | Advantage | Description | |---|---| | **Instant First Paint** | The first part of the HTML (header, skeleton) is visible right away | | **Lower TTFB / LCP** | The server doesn't wait for the render to finish to start responding | | **Smooth data loading** | Sections can be sent as soon as their data is ready | | **Suspense support** | Components with `React.Suspense` are automatically streamed later | | **Edge rendering** | The stream works great on a CDN / edge server | --- ## What this looks like in the browser ```javascript [Server starts rendering App] ↓ Sends <html><head>...</head><body> ↓ Sends <Header> (ready instantly) ↓ While waiting for the API → sends <Skeleton /> ↓ When data arrives → replaces <Skeleton> with <Content /> ↓ Finishes the stream </body></html> ``` The user sees: 1. The interface skeleton within milliseconds, 2. Content loading in smoothly, 3. No "blank loading screen". --- ## Combined with React Suspense Streaming SSR unlocks the full potential of `Suspense`: ```javascript <Suspense fallback={<Loading />}> <Comments /> </Suspense> ``` - `<Loading />` is rendered and streamed right away, - `<Comments />` is added **later**, once the data has loaded, and React correctly inserts it in place without re-rendering the whole page. --- ## Where Streaming SSR is used - **Next.js 13+ (App Router)** - used by default. - **Remix, Astro, Qwik, SvelteKit** - also implement streaming SSR. - Supported on **Node.js, Deno, Edge (Cloudflare, Vercel)**. --- ## Potential difficulties | Problem | Description | |---|---| | **Caching** | Streamed responses cannot simply be cached as finished HTML | | **Errors mid-stream** | It's harder to roll back HTML that has already been sent | | **Debugging complexity** | It's harder to see at which stage something went wrong | | **Infrastructure** | You need servers that support streaming (HTTP chunked encoding) | --- ## Summary **Streaming SSR** = "next-generation SSR": - Delivers HTML **gradually**, without waiting for the render to finish; - Lets the user **see content sooner**; - Works great with **React 18 + Suspense**; - But requires careful management of streams, caching, and errors.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.