深入理解 SSR/CSR 与 SPA/MPA:现代前端渲染模式详解

前言

在学习现代前端框架时,你可能会发现它们的 SSR(服务端渲染)与传统后端框架的 SSR 似乎不太一样。这篇文章将详细解释它们的本质区别,以及 SSR/CSR 和 SPA/MPA 这两个维度的概念关系。

传统后端 SSR vs 现代前端 SSR

传统后端 SSR(PHP、JSP、Rails)

工作流程:

1
2
3
浏览器 → 请求页面 → 服务器生成完整HTML → 返回HTML → 浏览器显示

每次交互都重复这个过程

特点:

  • 纯服务器渲染,返回的是完整的静态 HTML
  • 每次交互都需要刷新整个页面
  • JavaScript 只是点缀(表单验证、简单动效)
  • 模板引擎在服务器端运行(如 PHP、EJS、Jinja2)

现代前端框架 SSR(Next.js、Nuxt、Remix)

工作流程:

1
2
3
4
5
首次访问:
浏览器 → 服务器SSR → 返回HTML + JS Bundle → Hydration → 变成SPA

后续导航:
客户端路由 → 仅获取数据 → 客户端渲染 → 无刷新更新

核心区别:

1. Hydration(水合)过程

  • 服务器渲染初始 HTML(快速首屏)
  • 同时发送完整的 React/Vue 组件代码
  • 客户端”激活”这些 HTML,绑定事件和状态
  • 之后变成完整的交互式应用

2. 同构/通用渲染

  • 同一套组件代码既能在服务器运行,也能在客户端运行
  • 传统 SSR 是完全不同的模板系统

3. 渐进式增强

  • 首次加载:SSR 保证快速首屏和 SEO
  • 后续交互:SPA 模式,无刷新页面切换
  • 传统 SSR 每次都是完整页面刷新

4. 数据获取策略

  • 可以在服务器、客户端或两者都获取数据
  • 支持流式 SSR、增量静态生成等高级特性

形象类比

  • 传统 SSR:每次都点外卖,送完整的餐食
  • 现代 SSR:第一次送完整餐食+厨具,之后你自己在家做菜(客户端渲染)

所以现代框架的”SSR”更准确说是 SSR + CSR 的混合模式,充分利用了服务器和客户端的各自优势。


SSR/CSR 与 SPA/MPA 的概念关系

这是两个不同维度的概念,经常被混淆:

两个维度

1
2
3
4
5
6
7
维度1:渲染位置(Where)
├─ SSR (Server-Side Rendering) - 服务器渲染
└─ CSR (Client-Side Rendering) - 客户端渲染

维度2:应用架构(How)
├─ MPA (Multi-Page Application) - 多页应用
└─ SPA (Single-Page Application) - 单页应用

可能的组合

1. 传统 MPA + SSR(传统网站)

1
2
3
4
PHP、JSP、Rails、Django 模板

每个URL → 独立的HTML文档 → 服务器渲染
页面跳转 → 完整刷新 → 加载新文档

示例:

  • WordPress 博客
  • 传统企业网站
  • 电商网站(早期)

2. 纯 SPA + CSR(传统前端应用)

1
2
3
4
5
Create React App、Vue CLI 默认模式

只有一个HTML → 空壳 <div id="app">
所有内容 → JavaScript渲染
路由切换 → 无刷新,JS控制

示例:

  • Gmail
  • Notion
  • 后台管理系统

3. SPA + SSR(现代框架)✨

1
2
3
4
5
Next.js、Nuxt、Remix

首次加载 → SSR渲染HTML
Hydration → 变成SPA
后续导航 → 客户端路由(SPA模式)

示例:

  • Vercel 官网(Next.js)
  • Nuxt 官网(Nuxt)
  • 现代电商网站

4. MPA + CSR(少见)

1
2
多个HTML页面 → 每页都主要靠JS渲染
(不常见,没什么优势)

核心区别对比

MPA vs SPA

特性 MPA SPA
页面数量 多个 HTML 文档 单个 HTML 文档
导航方式 完整页面刷新 JS 动态更新 DOM
路由 服务器路由 客户端路由
状态保持 困难(需 session/cookie) 容易(内存中)
初始加载 只加载当前页 加载整个应用
SEO 天然友好 需要特殊处理

SSR vs CSR

特性 SSR CSR
渲染位置 服务器 浏览器
首屏速度 快(直接返回 HTML) 慢(需等 JS 执行)
SEO 友好 需要额外处理
服务器压力 较大 较小
交互延迟 TTI 较慢(需 hydration) TTI 较快(已加载)
复杂度 高(同构代码) 低(纯前端)

实际例子

传统 MPA + SSR:

1
2
3
4
5
https://example.com/users      ← 独立 HTML(服务器渲染)
https://example.com/products ← 独立 HTML(服务器渲染)
https://example.com/about ← 独立 HTML(服务器渲染)

点击链接 → 白屏 → 加载新页面

SPA + SSR (Next.js):

1
2
3
4
https://example.com            ← 入口 HTML(SSR)
→ /users ← 客户端路由(无刷新)
→ /products ← 客户端路由(无刷免)
→ 刷新页面 → 该页面 SSR 渲染

关键理解

SSR ≠ MPA

  • SSR 说的是”在哪渲染”(服务器还是客户端)
  • MPA 说的是”应用结构”(单页还是多页)
  • 现代框架实现了:SPA 架构 + SSR 能力

为什么现代框架选择 SPA + SSR?

  1. 兼顾首屏性能:SSR 提供快速的 FCP(First Contentful Paint)
  2. 兼顾用户体验:SPA 提供流畅的页面切换
  3. 兼顾 SEO:服务器返回完整 HTML
  4. 兼顾开发体验:组件化开发,代码复用

技术演进路线

1
2
3
4
5
6
7
传统 MPA + SSR(2000s)

纯 SPA + CSR(2010s)

SPA + SSR(2015s - Now)

未来:Islands Architecture、Streaming SSR、RSC(React Server Components)

总结

现代前端框架的 SSR 与传统后端 SSR 最大的区别在于:

  1. Hydration 机制:服务器渲染 + 客户端激活
  2. 同构代码:一套代码两端运行
  3. 混合模式:首屏 SSR + 后续 CSR
  4. 架构选择:SPA 的流畅体验 + SSR 的性能优势

这种”两全其美”的方案,让我们既能享受 SPA 的开发体验和用户体验,又能获得传统 SSR 的性能和 SEO 优势。这就是 Next.js、Nuxt、Remix 等现代框架如此流行的原因!


参考资源