PerformanceArchitecture
CSR
Client Fetching
Generated: Calculating...

Client-Side Rendering

The browser receives an empty shell and then fetches the data using JavaScript. This allows for rich interactive experiences like real-time filtering and complex state management, but can be slower on initial load.

Environment
Browser Window
Verification Lab

Refresh to see the 'Loading' state trigger in your browser.

Strategy

Rendered entirely in the browser using `useEffect`. Ideal for interactive dashboards, search interfaces, and private user areas.

Hydration

React takes over after JS loads. The server sends zero initial content.

Inspect Network

Open DevTools > Network. Look forCache-Controlheader. For CSR, you will seeno-store / no-cache

Hydration Pipeline

Order of operations

Empty Shell

Server sends a minimal HTML file with almost no content.

Load JS

Browser downloads large JavaScript bundles (React + App code).

Data on Client

React executes in browser and makes API calls to fetch data.

Hydration

The page becomes interactive after JS finishes executing.

Implementation Blueprint
app/page.tsx
'use client';
import { useState, useEffect } from 'react';

export default function Page() {
  const [data, setData] = useState(null);

  useEffect(() => {
    // Fetched after the page loads in the browser
    fetch('/api/data').then(res => res.json()).then(setData);
  }, []);

  if (!data) return <Loader />;
  
  return (
    <div>{/* Render Data */}</div>
  );
}

CSR moves the rendering work to the user's device. While this increases the 'Time to Interactive', it enables the ultra-smooth transitions and state management that dynamic web apps require.

Live Demo

These products were fetched using Client-Side Rendering (CSR) in your browser.

Testing Tip

Refresh to see the "Initializing" state. Notice how the page shell loads first.Note: In this lab, we forced the CSR shell to be dynamic to show fresh cache headers.

Initializing Client Hydration...

Advanced Pattern: Selective Rendering

Scroll down to see the LazyHydrate component in action. Products after the first 4 are wrapped in an Intersection Observer. They won't actually mount or render until they enter the viewport, saving CPU cycles on the initial hydrate.

React stateuseEffect FetchIntersection Observer