Rendering

SPA / SSR / SSG の違い

Compare the three rendering strategies: SPA, SSR, and SSG. Understand when HTML is produced and how performance, SEO, and infrastructure requirements change.

Timeline: When is the HTML ready?

Three patterns side-by-side on a timeline. Columns flow from User → Server/CDN → Browser (1st paint) → JS Engine → Browser (2nd paint) → Interactive.

SPA
SSR
SSG
User
Server / CDN
Browser (1st Paint)
JS Engine
Browser (2nd Paint)
Interactive
① Request
② Empty shell
③ Empty paint (FCP)
④ JS DL + exec
⑤ Content paint (LCP)
⑥ Interactive
① Request
② Server render
③ HTML = paint
④ JS DL + hydrate
⑤ Interactive
① Request
Pre-built (CDN)
② CDN = paint
③ JS (opt) hydrate
④ Interactive
Request
Server work
Empty HTML shell
Build-time work
JS DL + exec
First paint
Interactive

Where does the work happen?

Compute cost always lands somewhere: build time, server, or client. The three patterns differ mainly in where the cost falls.

SPA
Build Small
Server API only
Client Heavy
SSR
Build Small
Server Heavy / request
Client Hydration
SSG
Build Heavy (once)
Server ≈ 0
Client Opt. hydration

Comparison Overview

Aspect SPA SSR SSG
When HTML is generated Server only for shell / browser afterwards Per-request on the server At build time, for every page
Delivery JS bundle + empty HTML shell Dynamic HTML (rendered each time) Static HTML files (CDN-ready)
Initial TTFB Fast (shell only) but FCP is slow Medium (depends on server work) Very fast (served directly from CDN)
SEO Weak if CSR-only; can be addressed by pairing with SSR/SSG Strong (returns complete HTML) Strong (returns complete HTML)
Content freshness Always fresh via API Fresh at request time Fresh as of build (rebuild to update)
Server requirements Static hosting + API server Always-on app server (Node.js, etc.) Static hosting only (S3 / CDN)
Representative frameworks React, Vue, Angular, Svelte Next.js, Nuxt, SvelteKit, Remix Astro, Hugo, Jekyll, 11ty

Which to choose

SPA

When SPA is a good fit

  • Post-login dashboards / admin UIs (SEO not required)
  • Complex forms and interactions as the core experience
  • Backend is cleanly separated as an API
  • Prioritize post-load interactivity over initial render
SSR

When SSR is a good fit

  • Per-user content (carts, personalized recommendations)
  • HTML must differ by login state
  • Frequently updated content that also needs SEO (news, comments)
  • Authentication / authorization must run server-side first
SSG

When SSG is a good fit

  • Documentation sites, blogs, portfolios
  • Marketing sites / landing pages
  • Low update frequency (rebuilding is practical)
  • Cost and performance top priority (CDN only)

Frequently Asked Questions

Common points of confusion when learning these three patterns, gathered in one place.

Q. Modern frameworks (Next.js / Astro / Nuxt) support all modes. How do I choose?
Pick per page, not per site. Within the same project, use SSG for marketing pages, ISR for the blog, SPA (CSR) for the logged-in dashboard, and SSR for API-driven dynamic pages. In Next.js and Nuxt, each page can declare its mode via export const dynamic = ... / export const revalidate = .... 'Pick one mode for the whole site' is outdated thinking.
Q. Is there a default answer to 'what should I start with'?
'Start with SSG and add SSR / ISR / CSR only when needed' is the modern default. Reasons: (a) SSG is the simplest and most resilient, (b) most pages really are static, (c) you can upgrade individual pages when required. Choosing SSR up front pays the server-complexity tax on every page. That said, if your product is primarily a logged-in app, SPA or SSR from the start is more natural.
Q. Where does 'hydration' enter the picture — SPA, SSR, or SSG?
In SSR and SSG — not in SPA. Hydration is the process of the client JavaScript reusing server- or build-time HTML to make it interactive, so it only applies where complete HTML is returned. A SPA starts from empty HTML and the browser draws everything, so there is no existing HTML to hydrate.
Q. Is ISR different from both SSG and SSR?
An extension of SSG. The base is SSG (build-time generation + CDN delivery), plus the ability to regenerate pages after the fact. Regeneration triggers: (a) time-based (revalidate), (b) on-demand (webhook). Unlike SSR, it does not compute every request — only when needed. It's a Next.js / Vercel feature; other frameworks have adopted similar strategies (e.g., Astro's swr).
Q. Is JAMstack just SSG?
Used almost synonymously, but strictly speaking they're different. JAMstack = JavaScript (client) + APIs + Markup (pre-built) — an architectural pattern. SSG is the 'pre-built markup' part specifically. 'JAMstack' usually refers to the whole philosophy: static markup + CDN delivery + APIs for dynamic needs. A mix of SSG + ISR + Edge Functions also counts as JAMstack in the broader sense.
Q. Which one has the best performance in the end?
It depends on which metric you care about. TTFB and LCP (initial paint) favor SSG — as web.dev's "Rendering on the Web" notes, Static rendering offers "fast First Paint, First Contentful Paint and Time To Interactive" thanks to direct CDN delivery of pre-built HTML. TTI (time to interactive) is comparable between SSR and SSG when hydration is the same. Continuous-operation responsiveness (click → next view) is fastest on SPA because no network round-trip is required. In short: initial paint → SSG, continuous interaction → SPA, balance of both → SSR with hydration tuning.

In practice, these often mix

Modern meta-frameworks (Next.js, Astro, Nuxt, etc.) let you mix SPA / SSR / SSG per route within one project. Rather than labeling a whole site 'SSG', it's common to pick per page: 'article pages are SSG, the logged-in dashboard is SPA, the checkout confirm is SSR.'