About this article
This article is the second deep dive in the “Frontend Architecture” category of the Architecture Crash Course for the Generative-AI Era series, covering rendering methods.
The decision “when and where to generate the HTML” — modern options diversify across browser, server, build time, and CDN edge. The article covers the four methods (CSR, SSR, SSG, ISR), modern technologies (Hydration, Islands, Streaming SSR, RSC), and “per-page method selection” as the modern default.
What is a rendering method in the first place
A rendering method is, roughly speaking, “the choice of when and where to assemble the content (HTML) of a web page.”
A cooking analogy might help. Cook to order in the kitchen (SSR), prepare in advance and just serve from the shelf (SSG), send only ingredients and let the customer finish at the table (CSR) — each differs in serving speed, freshness, and effort. Web pages are the same: the timing and place of assembly changes the balance of display speed, SEO, and server cost.
| Main method | When | Where |
|---|---|---|
| CSR (Client Side Rendering) | At runtime | Browser |
| SSR (Server Side Rendering) | At request | Server |
| SSG (Static Site Generation) | At build | Build server |
| ISR (Incremental Static Regeneration) | At first/update | Re-generated on server |
The modern standard is per-page method selection. One site need not mean one method.
Why rendering method selection matters
If you build every page the same way without thinking about rendering methods, something will always break. All-SSR explodes server costs, and all-CSR kills SEO. Reverse-engineering from business requirements to decide what fits each page is where frontend design skill shows.
Projects with wrong method choices have real accidents — server costs spiking on campaign day one forcing rewrites, or zero Google visibility killing acquisition. Just deciding “which page, which method” upfront prevents most of these.
Quick decision flow
Before diving into details, here are typical site types and their first-choice methods. Use this to get your bearings, then check each method’s details.
| Site type | First choice |
|---|---|
| Blog / docs | SSG (Astro) |
| Corporate site / LP | SSG or ISR |
| E-commerce | ISR + partial SSR |
| SNS / SaaS | SSR (Next.js App Router) |
| Admin dashboard | CSR (React SPA) |
| Realtime-critical app | CSR |
”When and where” to make the HTML
| Main method | When | Where |
|---|---|---|
| CSR (Client Side Rendering) | At runtime | Browser |
| SSR (Server Side Rendering) | At request time | Server |
| SSG (Static Site Generation) | At build time | Build server |
| ISR (Incremental Static Regeneration) | At first / update | Server regenerates |
Selection ties directly to performance, SEO, and ops cost. All-page SSR explodes server cost; all-page CSR crashes SEO. Reasoning back from business requirements about which method fits which page is the showcase of frontend design skill.
The modern default: per-page method selection. No need for one site = one method.
Quick decision flow
Before details, the first candidate per typical site type. Anchor here, then check details per method.
| Site type | First choice |
|---|---|
| Blog / docs | SSG (Astro) |
| Corporate / LP | SSG or ISR |
| E-commerce | ISR + some SSR |
| SNS / SaaS | SSR (Next.js App Router) |
| Admin / dashboard | CSR (React SPA) |
| Real-time-critical app | CSR |
CSR (Client Side Rendering)
CSR sends “empty HTML and JS” to the browser; the browser executes JavaScript to build the DOM. The basic SPA (Single Page Application) form — naive React / Vue use is essentially this.
flowchart TB
BROWSER([Browser])
HTML["index.html + bundle.js<br/>(near-empty HTML)"]
EXEC["Run JS → build DOM"]
API["Fetch API → update view"]
BROWSER --> HTML --> EXEC --> API
classDef browser fill:#fef3c7,stroke:#d97706;
classDef step fill:#dbeafe,stroke:#2563eb;
class BROWSER browser;
class HTML,EXEC,API step;
Page transitions don’t full-load — partial updates make interaction extremely fast once loaded. But initial load downloads all JS, then runs, then fetches APIs to render — initial display tends to be slow. Empty HTML means Google’s crawler doesn’t see content, decisively weak on SEO.
| Strengths | Weaknesses |
|---|---|
| Fast page transitions, good UX | Slow initial display |
| Server only delivers static files | Weak SEO, JS required |
Admin / dashboards / login-after apps — uses prioritizing operability without SEO are optimal.
SSR (Server Side Rendering)
SSR generates HTML on the server per request and returns it. Same in essence as classical PHP / Rails / Django, but modern SSR renders React / Vue components server-side.
[Browser] ──(request)──→ [Server]
React/Vue generates HTML
←────(complete HTML)──── + Hydration JS
Browsers receive complete HTML, so initial display is fast and SEO is strong. Per-request server processing increases load and cost over static delivery substantially. High-traffic sites combine with CDN caching.
| Strengths | Weaknesses |
|---|---|
| Fast initial display, strong SEO | Server load and latency |
| Returns dynamic latest data | Cost increase at scale |
The default mode of Next.js / Nuxt / Remix. The favorite when SEO and interactivity are both required.
SSG (Static Site Generation)
SSG pre-generates all pages at build time as static files; CDN just delivers afterward. Zero server processing at request time, so fastest, cheapest, most outage-resilient delivery.
[CI/CD build]
All URLs → HTML generation
↓
[CDN delivery] ← pre-generated
Astro, Hugo, Jekyll, Eleventy are typical; shines on content-centric sites (blogs, docs, marketing). Downside: build time. Past several thousand pages, builds can take tens of minutes. “Re-build whole site on every update” also makes it weak for frequent updates.
| Strengths | Weaknesses |
|---|---|
| Fastest, cheapest, CDN-complete, outage-resilient | Build time |
| Hard to handle per-user content | Weak on frequent updates |
For blogs, docs, LPs, SSG is optimal. This series’s host senkohome.com also runs on Astro SSG.
ISR (Incremental Static Regeneration)
ISR is the good-of-both hybrid between SSG and SSR. Pre-generates main pages at build, then re-generates in the background after a period. Users always get cache-served HTML immediately while data freshness is maintained.
1. Build: pre-generate main pages
2. Access: serve cache if within window
3. Window expired: regenerate in background
4. Next access shows new version (stale-while-revalidate)
Next.js originated this, solving SSG’s “rebuild everything on every update” problem. E-commerce product pages (price and inventory change often, basics fixed) and news article pages — “semi-static, semi-dynamic content” is optimal.
A breakthrough method solving SSG’s weakness directly. Optimal for many-page sites with some frequent updates.
Hydration and Islands
Hydration adds interactivity via JavaScript to HTML generated by SSR or SSG. After the browser receives “static HTML” generated server-side, JS mounts and event listeners register — only then do button clicks and other interactions function.
[SSR HTML] → display in browser (not yet interactive)
↓
[Load and run JS] → Hydration (events activated)
↓
[Interactive]
The problem: re-running all the page’s JS is costly. The solution: Islands Architecture — a paradigm shift where “only interactive parts ship JS.” Astro is the canonical example, keeping 99% of pages as static HTML and running only interactive parts (cart, etc.) as small JS islands.
Astro’s Islands is the modern optimum, dramatically reducing JS shipping and reconciling LCP and INP.
Streaming SSR
Streaming SSR is the new method that streams to the browser as parts become ready rather than returning all HTML at once. Modern React / Next.js App Router / Remix support it as standard, solving “a slow API blocks the whole page.”
<html>
<head>...</head>
<body>
<Header /> ← sent immediately
<MainContent /> ← sent immediately
<Suspense> ← deferred with fallback UI
<SlowData /> ← streamed in after data arrives
</Suspense>
</body>
In traditional SSR, even one slow API made all HTML wait, so “the slowest part decides whole-page speed.” With Streaming, the skeleton returns first and slow parts show loading UI — TTFB (Time To First Byte) improves dramatically.
RSC (React Server Components)
RSC (React Server Components) is a new paradigm running React components on the server. Traditional React all ran in the browser; RSC runs server-side and ships only the result.
| Server Components | Client Components | |
|---|---|---|
| Run location | Server | Browser |
| JS shipped | No | Yes |
| Direct DB access | Possible | Impossible |
| useState / useEffect | Not possible | Possible |
RSC’s biggest value is JS-bundle reduction. Components for data fetching and shaping — “display only” — run server-side, shipping only the resulting HTML; only interactive parts ship JS, reducing what users download substantially.
The default of Next.js App Router. The fundamental answer to the JS-bundle problem.
Method comparison
Lining up the four rendering methods reveals each one’s strong area. “None is omnipotent,” so picking and combining per business need is modern.
flowchart LR
subgraph CSR["CSR (Client Side)"]
CSR1["Browser JS<br/>builds HTML"]
end
subgraph SSR["SSR (Server Side)"]
SSR1["Server generates HTML<br/>per request"]
end
subgraph SSG["SSG (Static)"]
SSG1["Static HTML<br/>at build time"]
end
subgraph ISR["ISR (Incremental)"]
ISR1["SSG-based,<br/>regenerate stale only"]
end
REQ([HTTP request]) --> CSR1
REQ --> SSR1
REQ --> SSG1
REQ --> ISR1
CSR1 -. "SEO×<br/>slow first display" .- BAD1[Weak]
SSR1 -. "high cost<br/>server-dependent" .- BAD2[Weak]
SSG1 -. "no dynamic update" .- BAD3[Weak]
ISR1 -. "comprehension cost" .- BAD4[Weak]
classDef ok fill:#dbeafe,stroke:#2563eb;
classDef bad fill:#fee2e2,stroke:#dc2626;
class CSR,SSR,SSG,ISR ok;
class BAD1,BAD2,BAD3,BAD4 bad;
| Aspect | CSR | SSR | SSG | ISR |
|---|---|---|---|---|
| First display | × | ◎ | ◎ | ◎ |
| SEO | × | ◎ | ◎ | ◎ |
| Server cost | ◎ | × | ◎ | ◯ |
| Dynamic update | ◎ | ◎ | × | ◯ |
| Outage resilience | ◯ | × | ◎ | ◯ |
| Build time | ◯ | ◯ | × | ◯ |
SSG is weak on “build time and dynamic updates”; SSR is weak on “cost and outage resilience” — each method has clear trade-offs. ISR balances these well, but at the cost of complex internals raising the comprehension bar.
”All-page SSR” night fire (industry case)
“A project with all marketing pages (which would be fine static) on Next.js SSR ran out of Vercel function-execution quota on the first night of a campaign and had to switch to static generation overnight” is a story repeated in many sites. Server cost growing linearly with traffic is what’s scary about SSR; campaigns and viral SNS hits spin the cost meter instantly.
A new-grad team builds an e-commerce site on Next.js SSR; a Friday-evening TV-tied campaign spikes requests, and Monday morning’s invoice shocks the manager — same family. The lesson is simple: starting with Static First would have avoided the accident.
Trying to build product detail and admin pages with the same method always makes one unhappy. Static for static-OK pages (SSG/ISR), SSR only for genuinely dynamic, CSR after login — “per-page selection” is the only way to reconcile cost, UX, and operations.
“All-page SSR” is a time bomb. Start Static First; dynamicize only required parts.
Page-type × method ladder
Note: industry rates as of April 2026. Periodic refresh required.
“One site = one method” breaks down; explicitly sort method by page nature — modern default.
| Page type | Recommended | Reason | Revalidate |
|---|---|---|---|
| Top / LP | SSG | Fixed, fastest, cheapest | Build time only |
| Blog / docs | SSG | Low update frequency, SEO important | Build time only |
| Product list | ISR | Catalog semi-fixed, inventory dynamic | 60s |
| Product detail | ISR + CSR (inventory only) | Basic info static, inventory only dynamic | 300s |
| News article | ISR | Mostly fixed after publish | 600s |
| Cart | CSR or SSR | Per-user, latest required | — |
| Login-after dashboard | CSR | No SEO, operability priority | — |
| Admin | CSR | No SEO, auth required | — |
ISR revalidate is 60-600 seconds as standard. Shorter dilutes ISR’s value (becomes SSR-equivalent); too long lets users see stale info longer. Adjust around Next.js’s revalidate: 60 baseline per page nature — practical operations.
Even within one site, methods cut per page. Giving up on unifying to one method is modern.
Rendering-design traps
Common method-selection failures. All lead to performance drop, cost explosion, SEO loss.
| Forbidden move | Why |
|---|---|
| All marketing pages on SSR | Server cost explodes proportionally to traffic. Classic Vercel function-execution-quota exhaustion |
| SEO-required site on CSR | Google crawler JS execution lags days to weeks; freshness-demanding sites collapse |
| SSG for sites with 10k+ pages | Builds take 30+ minutes. Switch to ISR for incremental builds |
| Streaming SSR without Suspense | One slow API blocks all HTML. TTFB worsens significantly |
| All fetching in Client Components | RSC benefit lost. Push data fetching to Server Components |
ISR revalidate set to 1 second | Effectively SSR-cost. 60+ seconds is practical |
| Re-fetch all data per page transition | TanStack Query caching cuts this dramatically |
| SSG-ifying auth-required pages | Login state can’t be determined at build time. SSR / CSR required |
| Forgetting font / image preload | LCP-killer classic. Auto via Next/Font / Next/Image |
| Trusting “SSR makes everything fast” | One slow API blocks all HTML, TTFB disaster. Streaming SSR + Suspense is required |
| Deferring SEO as “build CSR, handle it later” | SSR migration costs more than greenfield. If SEO matters, build SSG/SSR/ISR from the start |
The 2022 Vercel Serverless Function billing accident: Bots accessed SSR pages, producing six-figure dollar bills. “Static First” — static-OK pages stay static — is the rule.
All-SSR is a time bomb. Page-type splitting is the only correct answer.
AI decision axes
| AI-era favorable | AI-era unfavorable |
|---|---|
| Next.js App Router (RSC + file routing) | Custom SSR frameworks, custom routers |
| Astro (Islands + simple boundaries) | Hand-rolled complex Hydration strategies |
| Convention-based RSC / Client Components boundaries | All-CSR with hand-rolled data fetching |
| Standardized Suspense / Streaming | Custom loading-state management |
- Use methods per page (don’t unify whole site)
- Static First (SSG/ISR first, only required parts SSR/CSR)
- Pick convention-based FWs (Next.js App Router / Astro)
- Mind JS-bundle reduction (RSC / Islands cut shipping size)
Selection by case
Choose rendering methods at the use-case granularity. Mixing methods per page within one site is modern design.
| Use case | Recommended |
|---|---|
| Blog / docs | SSG (Astro / Next SSG) |
| E-commerce | ISR + SSR (product ISR, cart SSR) |
| Login-required admin | CSR (no SEO) |
| News / media | ISR (balance of update + speed) |
| LP / marketing | SSG (fastest, cheapest) |
| Dashboard SaaS | SSG + CSR (shell static, content dynamic) |
What you must decide — what’s your project’s answer?
Articulate your project’s answer in 1-2 sentences for each:
- Main rendering method (per-page basis)
- Hydration strategy (whole / Islands / Partial)
- RSC adoption
- Build frequency (for SSG)
- ISR revalidate window (seconds)
- Server-failure fallback method
Summary
This article covered rendering methods — CSR/SSR/SSG/ISR, Hydration/Islands, Streaming SSR, RSC.
Not “which is strongest” but “which fits which page.” Pick by use case, lean on convention-based FWs — the 2026 realistic answer.
The next article covers state management (useState / Context / Redux / Zustand / TanStack Query).
Back to series TOC -> ‘Architecture Crash Course for the Generative-AI Era’: How to Read This Book
I hope you’ll read the next article as well.
📚 Series: Architecture Crash Course for the Generative-AI Era (32/89)