Stream, don't spin
Flush the static shell at once; stream each slow part into its slot.
Guillermo Rauch@rauchgtl;DR: everything gets faster, worldwide. Thanks to streaming and leveraging the edge for the initial render, the user rarely would rarely, if ever, see a spinner. (Have you ever seen Google Search results or Amazon render a spinner? No. Because they stream!)
Guillermo Rauch@rauchgWhy does amazon.com feel so snappy? Zoom out, behold: the power of streaming. … Above the fold, instant. Below? Streamed over time.
Guillermo Rauch@rauchgWithout PPR: spinner galore With PPR: bliss
Guillermo Rauch@rauchgBecause of RSC and streaming, we don't need to download MBs of JS and then make a bunch of `fetch` waterfalls to render the dynamic parts. While the skeleton is flushed, and the JS / CSS / fonts are downloaded, the stream from the renderer next to origin database is cooking.
Demo 1 rebuilds his Amazon point: above the fold instant, the rest streamed in.
Reload the product page
Press Reload and count the spinners on each side.
Client-rendered SPABad
Streamed shellGood
// app/product/[id]/page.tsx: the shell is static, the holes stream in
export default async function Page({ params }) {
const { id } = await params;
return (
<ProductShell id={id}>
<Suspense fallback={<PriceSkeleton />}><Price id={id} /></Suspense>
<Suspense fallback={<ReviewsSkeleton />}><Reviews id={id} /></Suspense>
<Suspense fallback={<RecsSkeleton />}><Recommendations id={id} /></Suspense>
</ProductShell>
);
}
async function Price({ id }) {
const { price, stock } = await getInventory(id); // runs next to the database
return <PriceTag price={price} stock={stock} />;
}
Scrub both loading sequences
Drag the time slider, or press Play.
Client-rendered SPABad
Streamed shellGood
Why it matters, pros and cons
Why it matters
The shell needs no data, so it leaves the edge first. Slow parts fill their own holes.
Pros
- First content at TTFB, not after JS and a fetch waterfall.
- A slow part never holds a fast one; slots resolve alone.
- Queries start on the server, next to the database.
Cons
- Streamed slots need fixed sizes, or they shift on arrival.
- Once the 200 is flushed you can't redirect; fail in-slot.
- Too many tiny boundaries pop in like confetti; group them.