Comparisons
Pairs that get conflated in real conversations, and in real pull requests. Neither column wins — what decides is the requirement. Each record leads with the confusion, because the confusion is the reason the record exists.
Client-side rendering vs Server-side rendering
SSR is described as "faster", which is not a claim you can make without saying faster at what. SSR usually improves the time until meaningful content is visible, because bytes arrive already shaped as content. It does not improve — and can worsen — the time until the page is interactive, because that still waits on the bundle downloading, parsing, executing and hydrating, and now there is a server render on the critical path as well. The result is a page that looks ready and is not, which is a specific kind of bad: users click, nothing happens, and they click again. The second confusion is that this is one global switch. It is per route. A marketing page, a product listing and an internal dashboard in the same application have three different right answers, and modern frameworks exist largely to let you mix them.
Application surfaces behind a login, where the first paint is a shell nobody indexes, navigation continuity matters more than first load, and the server has no advantage in producing the markup.
Content the first paint must actually contain — for search engines, link previews, users on slow connections, or anything where a shell is a worse experience than waiting slightly longer for real content.
| Dimension | CSR — the server sends a shell and JavaScript builds the page | SSR — the server renders HTML per request and the client hydrates it |
|---|---|---|
| First HTML contains | A shell | Rendered content |
| Time to meaningful content | After bundle downloads, parses, runs and fetches | On first paint of the response |
| Time to interactive | When the bundle has run | When the bundle has run and hydration completes |
| Server cost | Static file serving | A render per request, plus data fetching on the server |
| Failure mode | Blank screen if the bundle fails | Visible but dead UI until hydration; mismatches if the environments differ |
| Data fetching | From the browser, after JS runs | On the server, before the response — often nearer the data |
| Caching | The shell caches trivially | Per-request HTML is harder to cache and often personalised |
| Best measured by | When content appears and when input is answered | The same two — and the gap between them, which is the SSR-specific risk |