Part V — Rendering web applications in depth
32. Rendering models: CSR, SSR, SSG, ISR
| Model | HTML generated | First paint | SEO/no-JS | Server load |
|---|---|---|---|---|
| CSR (Client-Side Rendering) | In the browser, by JS, after download | Slow (blank until JS runs + fetches data) | Poor without extra work | Low (static file hosting) |
| SSR (Server-Side Rendering) | On the server, per-request | Fast (real HTML immediately) | Good | High (a server render per request) |
| SSG (Static Site Generation) | At build time, once | Fastest (pure static file) | Good | Lowest (CDN-served) |
| ISR (Incremental Static Regeneration) | At build time, then regenerated on a schedule/on-demand | Fast, can go slightly stale | Good | Low, with periodic regen cost |
A CSR page's actual load sequence explains why it "feels" slower even on a fast connection:
CSR: HTML shell (empty <div id="root">) -> download JS bundle -> execute JS
-> JS fetches data -> JS renders DOM -> user sees content
(4 sequential round-trip-dependent steps before anything visible)
SSR: Server fetches data -> server renders full HTML -> browser paints
immediately -> JS bundle arrives later and "hydrates" (§34) for
interactivity (1 round trip before visible content)
Real frameworks let you mix these per-route: Next.js/Nuxt/SvelteKit can SSR a dashboard, SSG a marketing page, and ISR a blog — the "rendering model" is a per-page decision, not an app-wide one.