Careeroza
Streaming
Chunked HTML
With Suspense, the server sends the response in chunks using HTTP chunked transfer. The browser renders each chunk as it arrives; React inserts the streamed parts in place with tiny inline scripts.
Example
Watch the chunks arrive with curl's no-buffer flag:
curl -N localhost:3000/products/42Example output
<!DOCTYPE html><html>...<h1>Redmi Note 14</h1>
<!--$?--><template id="B:0"></template><p>Loading reviews...</p><!--/$-->
... (0.4 s later)
<div hidden id="S:0"><section>Reviews (4.3★)</section></div>
<script>$RC("B:0","S:0")</script>Things That Break Streaming
- A proxy or CDN that buffers responses (nginx: set
X-Accel-Buffering: noorproxy_buffering offfor Next.js). - Compression middleware that waits for the full body.
- Awaiting everything at the top of the page instead of inside Suspense boundaries.
Order of Completion
Example
Streamed parts arrive in the order their data finishes. A slow part does not block faster parts after it:
const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
const log: string[] = [];
async function boundary(name: string, ms: number) {
await sleep(ms);
log.push(name + ' (' + ms + ' ms)');
}
async function main() {
log.push('shell');
await Promise.all([boundary('recommendations', 90), boundary('delivery', 30), boundary('reviews', 60)]);
log.push('end');
console.log(log.join('\n'));
}
main();Output
shell delivery (30 ms) reviews (60 ms) recommendations (90 ms) end