WhollySoftware
Back to blogWeb

React Server Components in Practice: What Actually Moved Server-Side

Wholly Software TeamMarch 5, 20255 min read
React Server Components in Practice: What Actually Moved Server-Side

When Server Components landed as the default in the App Router, our first instinct on a client analytics dashboard was to convert everything — every table, every card, every filter panel — into a server component and call it a win. That was the wrong instinct. Anything with local UI state, like a filter panel that toggles without a round trip, needs to stay a client component, and we ended up reverting about a third of our initial conversions.

The actual win showed up in data-heavy list views. A project directory page that used to fetch client-side with useEffect and show a loading spinner now fetches on the server and streams the shell immediately with Suspense boundaries around the slow parts. Time to first contentful paint on that page dropped from around 1.8s to 900ms on a mid-tier connection, because the client never had to wait for a hydration cycle before it could even ask for data.

The part that tripped us up was mixing server and client boundaries carelessly. Passing a function as a prop from a server component to a client component fails silently in some cases and loudly in others, and we lost half a day debugging a chart component that wouldn't render because we'd passed an onClick handler two levels too deep. The fix was pushing interactivity to leaf components and keeping everything above them server-rendered.

Data fetching got genuinely simpler. Instead of a client-side fetch waterfall through three nested components, each server component fetches what it needs directly, and Next.js dedupes identical requests automatically within a render pass. We removed an entire SWR caching layer from one project because the server-side fetch plus route segment caching did the same job with less code.

Our rule now: default to server components, and only opt into 'use client' when you actually need state, effects, or browser APIs. It's a smaller win than the initial announcements suggested, but on data-heavy pages it's a real one, and it simplified our codebases more than it complicated them.

ReactNext.jsServer ComponentsWeb Performance
React Server Components in Practice: What Actually Moved Server-Side — Wholly Software