Next.js Curriculum
EasyRendering Paradigms100% Free25 min read

Evolution of Web Rendering: CSR, SSR, SSG, and ISR

The 30-Second Interview Answer

CSR ships a minimal HTML shell and executes JavaScript in the browser. SSR renders full HTML dynamically on every request on the server. SSG generates static HTML once at build time for instant CDN distribution, while ISR adds background regeneration using stale-while-revalidate headers without full rebuilds.

Learning Objectives

Compare performance characteristics (TTFB, FCP, LCP) across CSR, SSR, SSG, and ISR.

Explain the computational and cost trade-offs of per-request server rendering versus CDN edge caching.

Identify when to choose static generation with background revalidation over dynamic rendering.

Understand how search engine crawlers interpret client-hydrated single-page applications.

Prerequisites & Background Knowledge
Browser DOM lifecycleHTTP request-response cycleReact component rendering

Why Interviewers Care

Foundational screening question asked at nearly every tech company to gauge architectural maturity.

The Challenge

Compare and contrast CSR, SSR, SSG, and ISR. Explain the server overhead, Time to First Byte (TTFB), Largest Contentful Paint (LCP), and cache invalidation strategies for each paradigm.

Code Architecture & Implementation

1// 1. STATIC SITE GENERATION (SSG) / Default Static Prerender
2// Rendered at build time. Served globally from edge CDN.
3export default async function StaticMarketingPage() {
4 const data = await fetch('https://api.cms.com/about', {
5 // In Next.js 15+, fetch defaults to no-store unless cached explicitly
6 next: { revalidate: false } // or export const dynamic = 'force-static'
7 }).then(res => res.json());
8
9 return <div>{data.headline}</div>;
10}
11
12// 2. INCREMENTAL STATIC REGENERATION (ISR)
13// Stale-while-revalidate: served from CDN cache, revalidated in background every 60s
14export default async function ProductCatalogPage() {
15 const products = await fetch('https://api.store.com/products', {
16 next: { revalidate: 60 } // background regeneration window
17 }).then(res => res.json());
18
19 return <ul>{products.map((p: any) => <li key={p.id}>{p.title}</li>)}</ul>;
20}
21
22// 3. SERVER-SIDE RENDERING (SSR) / Dynamic Request-Time Rendering
23// Runs on every HTTP request on Node.js / Edge server. Ideal for private/auth data.
24import { cookies } from 'next/headers';
25
26export default async function UserDashboard() {
27 const cookieStore = await cookies(); // Accessing dynamic request info triggers SSR
28 const token = cookieStore.get('session')?.value;
29 const user = await fetch('https://api.auth.com/me', {
30 headers: { Authorization: `Bearer ${token}` },
31 cache: 'no-store'
32 }).then(res => res.json());
33
34 return <div>Welcome, {user.name}</div>;
35}

Architectural Explanation

The Rendering Strategy Spectrum

StrategyWhen HTML Is CreatedWhere It Is ServedTTFBServer CPU LoadFreshness Guarantee
CSRIn browser via JSCDN (empty shell)Blazing fast shell, slow FCPZero origin computeReal-time on client fetch
SSGBuild timeCDN edge cacheFastest (<50ms)Zero origin computeFixed at build time
ISRBuild time + backgroundCDN edge cacheFast (<50ms)Low background workerStale up to $N$ seconds
SSROn every requestOrigin server / EdgeModerate (150–500ms)High per userGuaranteed real-time

Core Architectural Mechanics:

  1. CSR (Client-Side Rendering): Traditional SPAs (Create React App, pure Vite). The server delivers an empty <div id="root"> and a large JavaScript bundle. The browser downloads, parses, and executes React before rendering content. This causes slow First Contentful Paint (FCP) and poor SEO for crawlers with strict rendering timeouts.
  2. SSG (Static Site Generation): Next.js pre-renders HTML and JSON at build time. The static files are pushed to an Edge CDN. User requests hit the nearest edge node with near-zero latency.
  3. ISR (Incremental Static Regeneration): Combines the latency benefits of SSG with data freshness. A page is served from edge cache. If a request arrives after the revalidation interval has elapsed, Next.js serves the stale cached page immediately while triggering a background regeneration worker. Once the new page renders successfully, the edge cache is purged atomically.
  4. SSR (Server-Side Rendering): The server renders full HTML per incoming HTTP request. This is required whenever the output depends on request-time information, such as cookies, auth sessions, or geo-IP headers.

Common Mistakes & Anti-Patterns

Believing ISR guarantees that the visitor who triggers the revalidation receives the fresh page immediately (they receive the stale page; subsequent visitors receive the updated page).

Using SSR for public blog posts or marketing pages that do not depend on user-specific session cookies.

Assuming CSR provides better overall performance because the server serves a static file, ignoring high client-side CPU parse/execution times on low-end mobile devices.

Interview Follow-Up Traps

Interviewer asks: "What happens if an ISR background revalidation throws a database connection error?" Trap answer: The site crashes with a 500 error. Correct answer: Next.js catches the background build error and continues serving the previous valid cached version indefinitely until a subsequent regeneration succeeds.

Interviewer asks: "Can you run SSG on pages that check authentication cookies?" Trap answer: Yes, with edge rewrites. Correct answer: No. Any component or layout that reads cookies() or headers() opts the route out of static generation into dynamic request-time rendering.

Frequently Asked Questions

What is stale-while-revalidate in the context of ISR?

It is an HTTP caching directive where clients are immediately served cached content while the server asynchronously generates and updates the cache in the background.

No. Next.js 15 changed fetch defaults to no-store (uncached). To enable caching, developers must explicitly specify next: { revalidate: N } or opt in via route segment configurations.

Choose SSR when the page content is highly personalized per user (e.g., private account dashboards) or requires immediate request-time query params or cookies.

Next.js prefetches the static React Server Component payload (RSC payload) and renders the page via client-side routing without triggering a full browser document reload.

Yes. On-demand revalidation can be triggered programmatically via revalidatePath() or revalidateTag() in Route Handlers or Server Actions.