Server vs Client Components (Next.js App Router): Boundaries, Hydration Cost, and Performance

A senior model for Next.js Server Components: what runs where, how client boundaries increase JS + hydration cost, and how to design component trees for performance.

F

Frontend Interview Team

March 01, 2026

2 min read
Server vs Client Components (Next.js App Router): Boundaries, Hydration Cost, and Performance

What you’ll learn

  • What Server Components are (and what they’re not)
  • What a client boundary really costs
  • How hydration cost shows up as long tasks and hurts INP
  • A practical decision framework for “should this be client?”

The mental model

In Next.js App Router:

  • Server Components run on the server. They can fetch data and render HTML without shipping component JS to the browser.
  • Client Components ship JS to the browser and can use hooks/state.

A "use client" file creates a client boundary.

The key tradeoff

More client boundaries → more JS shipped + more hydration work → worse INP risk.


A practical rule: keep "use client" low in the tree

Bad (client boundary high):

// app/page.tsx
'use client';
 
export default function Page() {
  return (
    <Layout>
      <Hero />
      <Content />
      <FilterPanel />
    </Layout>
  );
}

Now everything under Page becomes client.

Better: isolate interactivity:

// app/page.tsx (server)
export default async function Page() {
  const data = await fetchData();
  return (
    <Layout>
      <Hero />
      <Content data={data} />
      <FilterPanelClient />
    </Layout>
  );
}
 
// FilterPanelClient.tsx
'use client';
export function FilterPanelClient() {
  // hooks/state here
}

Interview questions

Q1) What’s the difference between SSR and RSC?

30-second answer: SSR renders HTML on the server but still often hydrates a client React tree. RSC lets you render components on the server without shipping their JS to the client at all.

Q2) Why can hydration hurt INP?

30-second answer: Hydration is main-thread work (parsing/executing JS, attaching listeners, running effects). If it creates long tasks, interactions are delayed.


Quick recap

  • Server components reduce client JS
  • Client boundaries have real cost
  • Keep "use client" low and isolated