Where Should You Render? A Field Guide to Web Rendering Strategies
CSR, SSR, SSG, ISR, and the edge — what each one actually optimizes for, the metrics that separate them, and a decision rule you can apply per route.
"Should this page be server-rendered?" is the wrong question, because it assumes one answer for a whole app. The right unit is the route. Each route has its own data freshness needs, its own SEO stakes, and its own tolerance for a blank first paint — and modern frameworks let you pick a strategy per route. This is a map of the options and when each wins.
The five strategies
- CSR (client-side rendering): ship an empty shell, fetch and render in the browser.
- SSR (server-side rendering): render HTML per request on the server.
- SSG (static site generation): render HTML once at build time.
- ISR (incremental static regeneration): SSG, but pages re-generate in the background after a TTL.
- Edge: SSR/ISR executed close to the user at a CDN node.
The metric that decides it
Most of the debate collapses into one number: time to first meaningful paint, and how it trades against data freshness. A useful mental model is that total perceived latency is roughly
CSR pushes but pays a large and a blank screen while data loads. SSG pushes both and toward their floor because the HTML is already sitting on a CDN — at the cost of freshness. The whole art is choosing which term you're willing to inflate.
Picking per route
Here's the rule I actually use when wiring up a Next.js app:
// Static by default — the content changes only when I redeploy.
export const dynamic = 'force-static'
export function generateStaticParams() {
return getAllSlugs().map((slug) => ({ slug }))
}
// A dashboard route, by contrast, opts into per-request rendering:
// export const dynamic = 'force-dynamic'The heuristic in one table:
| Route type | Freshness need | Best fit |
|---|---|---|
| Marketing / docs | Low | SSG |
| Blog / articles | Low–medium | SSG or ISR |
| Product listings | Medium | ISR |
| Personalized dashboard | Per-request | SSR / Edge |
| Highly interactive app | Client state | CSR shell |
A concrete example
This very blog is SSG. Every post is an MDX file compiled at build time into
static HTML and dropped onto a CDN — so $T_{\text{server}} = 0$ at request time.
The trade-off (content only updates on redeploy) is exactly right for writing:
articles don't change between deploys, and I'd rather pay the cost once at build
than on every read.1
If these were product pages with hourly price changes, I'd switch the same route to ISR with a short revalidation window and get 90% of the speed with a fraction of the staleness.2
The takeaway
Don't pick a rendering strategy for your app. Pick one per route, driven by how fresh the data must be and how much your users pay for a blank first paint. Frameworks made this a per-route decision on purpose — use that.