The Runtime Theory
Web Development

SPA vs MPA: When to Use Which

Single-page apps vs multi-page apps — tradeoffs in bundle size, SEO, time-to-interactive, and development complexity.

The Runtime Theory Team2 min read
▸ On this page

SPA vs MPA: When to Use Which

The fundamental architectural decision in web development is whether to build a Single-Page Application (SPA) or a Multi-Page Application (MPA).

Single-Page Application (SPA)

In an SPA, the browser loads a single HTML page and then dynamically updates the content using JavaScript. Navigation between "pages" is handled client-side — no full page reloads.

Examples

  • React apps with client-side routing (react-router)
  • Angular apps (@angular/router)
  • Vue apps (vue-router)

Pros

  • Fast navigation: Only data changes, not the whole page
  • Rich interactivity: Complex client-side logic, animations
  • Shared state: JavaScript state persists across "pages"
  • Offline support: Can cache data and work without a server

Cons

  • Large initial bundle: All JavaScript must download before the app works
  • SEO challenges: Search engines struggle with client-rendered content
  • Memory leaks: State accumulates in the browser tab
  • Slow Time to First Byte (TTFB): Server just sends a shell, not real content

Multi-Page Application (MPA)

In an MPA, every URL maps to a server-rendered HTML page. Navigating between pages causes a full page load.

Examples

  • Traditional server-rendered apps (Rails, Django, Laravel)
  • Modern SSR/SSG: Next.js with SSR/SSG, Nuxt.js with SSR/SSG

Pros

  • Instant rendering: Server sends complete HTML on first load
  • Better SEO: Search engines see real content
  • Lower memory usage: Browser doesn't hold state between pages
  • Smaller bundles: Only the JS for the current page loads

Cons

  • Full page reloads: Slower navigation, lost state
  • More server work: Each page requires server rendering
  • Limited interactivity: Complex client-side logic is harder

Modern Hybrid Approaches

Server-Side Rendering (SSR)

The server generates the full HTML on each request, then the client takes over for interactivity.

Next.js: getServerSideProps — renders on every request Nuxt.js: asyncData — renders on every request

Tradeoff: Fast initial load + SEO, but server must render every page.

Static Site Generation (SSG)

The server generates HTML at build time, not at request time.

Next.js: getStaticProps — generates at build time Nuxt.js: generate — pre-renders all pages

Tradeoff: Blazing fast initial load + can be CDN'd, but content must be known at build time.

Incremental Static Regeneration (ISR)

Static pages that can be updated in the background after build.

Next.js: revalidate option in getStaticProps

Tradeoff: Static performance + dynamic updates, but with eventual consistency.

Decision Matrix

Use caseChoose
Content site (blog, marketing)MPA / SSG — SEO + speed
Dashboard, admin panelSPA — rich interactivity
E-commerceHybrid (SSR/SSG) — SEO + performance
Chat, collaborationSPA + WebSockets — real-time
High traffic, read-heavyMPA / SSG — CDN cacheable

The Rendering Triangle

You can pick any two:

  • ✅ Fast initial load
  • ✅ Search engine friendly
  • ✅ Rich interactivity

SPA gives you #1 and #3 (not #2). MPA gives you #1 and #2 (not #3). SSR/SSG gives you #2 and #3 (slower than SSG).

Not started

Sign in to save your learning progress.

Sign in to save