Rendering Strategies Compared: Server-Side Rendering, Static Generation, and Client-Side Rendering
The same page can be built three fundamentally different ways: generated fresh on every request, generated once ahead of time, or assembled in the visitor's browser after the fact. Each answers "when does the HTML actually get built" differently, and that answer drives almost everything else about how the page performs.
Published July 6, 2026Client-side rendering sends the browser a nearly empty HTML shell and a JavaScript bundle; the browser downloads the bundle, executes it, fetches whatever data it needs, and only then builds the actual visible page in the DOM. Server-side rendering builds the full HTML on the server, for that specific request, and sends a page that already has visible content before any JavaScript runs. Static generation builds the full HTML too, but ahead of time, at build/deploy time rather than per request, and simply serves the pre-built file to every visitor.
What a visitor actually experiences with each
With pure client-side rendering, a visitor's first paint shows nothing meaningful — often a blank page or a loading spinner — until the JavaScript bundle has downloaded, parsed, executed, and fetched data. On a slow connection or an underpowered device, that gap can be seconds long, and search engine crawlers that don't execute JavaScript, or execute it unreliably, may see an empty page too. Server-side rendering and static generation both avoid this: the HTML that arrives already contains visible content, so first paint happens as soon as that HTML is parsed, independent of how long the JavaScript takes to show up afterward.
Hydration: the step that makes SSR and CSR different from what they look like
Server-rendered HTML looks complete but isn't interactive yet — clicking a button does nothing until the same JavaScript framework that runs in client-side rendering loads and "hydrates" the existing HTML, attaching event listeners and internal state to DOM nodes that already exist rather than creating them from scratch. This is why SSR pages can show a frustrating gap where the page looks done but buttons don't respond: the visible HTML arrived first, but time to interactive still depends on the same JavaScript bundle download and execution that client-side rendering needed, just running against existing markup instead of building it.
// simplified SSR flow
1. request arrives at server
2. server renders HTML with current data, sends it
3. browser paints the HTML immediately (visible, not yet interactive)
4. JS bundle downloads and hydrates the existing DOM (now interactive)
Where static generation wins outright
If the content is the same for every visitor and doesn't need to reflect data that changed in the last few seconds — a blog post, a documentation page, a marketing page — building it once at deploy time rather than re-rendering it on every single request is strictly cheaper and faster. There's no server-side rendering work happening per request at all; a static file gets served, which is also trivially cacheable at a CDN edge, since the same bytes go to every visitor. The trade-off is that content can only update on a new build/deploy, which is fine for a blog post and wrong for a live stock price.
Where server-side rendering earns its per-request cost
Pages where the content genuinely differs per request — a personalized dashboard, search results, anything reflecting the specific logged-in user or query parameters — can't be pre-built once at deploy time, because there's no single correct version to build ahead of time. SSR pays a real per-request rendering cost on the server, but in exchange gets a fast first paint with genuinely current, personalized content, which pure client-side rendering can only match by shipping personalization logic to the browser and accepting the blank-page delay while it runs.
Where client-side rendering still makes sense
Highly interactive, app-like interfaces — a spreadsheet, a design tool, an internal admin dashboard used constantly by the same logged-in users — often benefit less from fast first paint (the user isn't a first-time visitor bouncing off a slow page) and more from avoiding full-page reloads on every navigation. Once the initial bundle is loaded, subsequent interactions inside a CSR app can feel instantaneous because there's no server round trip rebuilding a full page for each click, just a data fetch and a local re-render. That model fits internal tools and logged-in apps far better than it fits a public marketing site or a content-heavy blog, where the first visit is the one that matters most.