Next.js App Router in Production: Server Components and Streaming Without the Ceremony
Streaming isn't a demo trick — it's how we keep dealer pages feeling instant while CMS data resolves. Notes from real storefronts.

The App Router pitches are always the same three-slide demo: a slow component wrapped in <Suspense>, a skeleton, fireworks. What the demo doesn't show is how streaming behaves when the page is assembled from CMS blocks, the marketing team reorders them weekly, and somebody put a map above the fold. Here's how it plays out on the dealer storefronts I work on at Revnix.
Server components changed the data flow, not just the syntax
The real win of RSC isn't async function Page() — it's deleting the client-side data layer for content pages. Inventory listings, spec tables and CMS sections fetch where they render, and the client bundle only carries what genuinely needs JavaScript:
// A CMS-driven section — zero client JS
export default async function InventorySection() {
const vehicles = await getInventory({ category: "compact-tractors" });
return <InventoryGrid vehicles={vehicles} />;
}Streaming with intent
We treat Suspense boundaries as an editorial decision, not a technical one. The hero, heading and navigation are static and ship instantly; below-the-fold sections — the heavy inventory grids, the dealer-location map — stream in behind skeleton shells that match final layout closely enough to avoid jank when they land. LCP comes from markup that was already on the server; the slow data never blocks the story.
- Static shell, streamed body. Every page paints its shell from cached CMS layout immediately.
- Boundaries where content blocks break. Editors reordering sections shouldn't break streaming — boundaries follow the block system, not the template.
- Loading states that respect layout. Skeletons sized to the real content avoid the CLS tax that erases your streaming win.
What I'd tell past me
Stop reaching for client components the moment something feels dynamic. Nine times out of ten, the dynamic part is one small interactive island inside a large static section — ship the section as a server component and hydrate the island. Our bundles got dramatically smaller the day we started asking which pixels need JavaScript, instead of which pages.