Is SPA the Same as CSR? On Rendering Strategies and Application Architecture
When I was doing frontend development, the popular technology was called SPA, which was something that contrasted with the old Django and PHP approaches. It meant running all the JavaScript on the frontend.
NextJs framework appeared with its SSR (server-side rendering) technology. So I always thought Next.js SSR did the same thing as Django and PHP.
Before SSR appeared, everything was about the "big three frontend frameworks" SPA applications. I thought SSR was meant to solve things that SPA couldn't handle, like SEO, so I equated CSR with SPA, also you'd always see these two terms together.
So I really thought SPA = CSR
Also because CSR handled most SPA examples.
Who belongs to whom, or who implements whom these questions started bothering me for a long time…
Terms first
Below, browser = client = frontend
not always precise but true in most cases.
As an exception, Next.js SSR components are a kind of frontend running on the server
CSR & SPA definitions
- SPA is an "application architecture"
- CSR is a rendering strategy
SPA's one-sentence definition: one HTML page, dynamically updating content through JS in the browser without reloading the entire page
SPA is an application architecture.
Here's the key point
SPA can be implemented through rendering strategies like CSR, SSG, SSR, which explains my original misconception that SPA=CSR.
The difference lies in how much responsibility the server takes. If we position Next.js SSR on the Server and Client Render spectrum, it sits right in the middle.
Unlike CSR which handles everything in the browser/client, and unlike pure server render which takes care of everything, it sits right in the middle.
SSR completely renders HTML at runtime, then sends HTML + not yet run JS files to the browser, and the browser starts to hydrate.
Just covered SPA vs CSR, now let me repeat with SPA vs SSR
SPA is a "client-behavior architecture" that defines an application's usage based on proactive client behavior, then executes the necessary JS for continuous dynamic rendering.
The reason SSR can be called server-side is because the HTML generation phase is handled by the server, though it's a semi-finished product that still needs to bring JS to the browser. So you could say it's server render, but the difference is:
- "True, pure server render" means the server directly outputs complete, usable HTML that the browser can immediately display and interact with, without needing additional JS to rebuild application state
- "True, pure server render" doesn't have the hydrate concept. Hydration is specific to modern frontend frameworks (React/Next.js). This traditional server render might also have JS, but that's just "progressive enhancement."
I think it took me years of exploration to slowly understand these concepts because in my career I never did pure server-side rendering…
The Routing Question
Q: Is SSG /about
→ /contact
client-side or server-side routing?
A: SSG is server-side rendering where the server generates HTML at build time; but when I use it, going from /about
to /contact
is actually client-side routing: the browser uses JS to handle page transitions, requests corresponding content from the server, updates the URL and injects content - the screen updates without full page reload.
SSR /about
→ /products/:id
is also client-side routing
SSR and SSG are server-side rendered the first time, but after that it's all handled by the client, which is why they can also be SPAs.
Actually, whether it's SSR or SSG, they're both pre-rendered HTML the first time, and then client-side routing handles everything after that, which is why they can also be SPAsSSR pre-renders at runtime
SSG pre-renders at buildtime, with no nodejs server afterward, just static hosting
Why SSR is faster compared to CSR
- CSR: Everything feels like it's running in the browser, users feel like I'm starting from 0.
From an HTTP request perspective, TTFB is fastest, but because the user experience starts from 0, you still have to wait for hydration after FCP, so TTI is slow
- SSR: FCP is better, the server gives you HTML first, but when it comes to TTI you wait for hydration again. There's that delay where you can see but can't interact - the FCP to TTI experience is more noticeable with SSR than with CSR where you're assembling everything yourself
- Pure server render: Fastest, because everything's done on the server side, browser sees the finished product directly, so TTI=FCP.
Of course, because you have to wait for the server to finish everything, TTFB is super slow from an HTTP Request perspective, but users don't feel it.
Best choice for users in poor network areas
- SSG: Although hydration is still needed, static files can leverage CDN caching better and have lower server dependency
- Between SSR vs CSR, choose SSR. At least you can see the HTML.
CSR requires assembly in the browser, so you have to wait for the JS bundle to download before seeing content
The Real Meaning of Single Page
From the above, SSR and SSG can both be SPAs, but they're clearly not Single Page, right? When I was doing frontend with Next.js, I didn't feel like that file structure was an SPA.
I think you need to compare relatively. In the old days, page transitions would completely refresh and then show you the content you wanted - this was pure server render, because the browser tells the server "I want XXX" and the server directly delivers XXX.
The meaning of single page isn't truly single page, but single page like. When SPA transitions between pages, the routing responsibility is actually in the browser - it's just that when the browser navigates, it tells the server "when I get there, I want to see XXX."
Also because Next.js uses file-based routing, you think of them as independent page-by-page units.
Single-page is about browsing experience, not the underlying architecture.
Anyone can be SPA
SSR and SSG can both be SPAs just like CSR.
The difference between SSR/SSG and CSR is that the first load is server-rendered, then subsequent navigation relies on client-side routing.
What SPA contrasts with is somewhat old-fashioned - the days when page transitions would white-screen. But actually I might not be able to precisely feel what SPA contrasts with, because my starting point was SPA from the beginning.