CSR_SSR_SSG_ISR渲染方案
一、核心概念对比
| CSR(客户端渲染) | SSR(服务端渲染) | SSG(静态站点生成) | ISR(增量静态再生) | |
|---|---|---|---|---|
| 渲染位置 | 浏览器 | 服务器 | 构建时 | 构建时 + 按需更新 |
| HTML 生成时机 | 运行时(浏览器) | 每次请求时 | build 时一次性生成 |
构建时生成,过期后按需重新生成 |
| 首屏速度 | 慢(需下载 JS 后渲染) | 快(直接返回 HTML) | 最快(直接返回静态文件) | 快(静态文件 + 按需更新) |
| SEO | 差(爬虫可能拿不到内容) | 好 | 最好 | 好 |
| 服务器压力 | 低(静态资源) | 高(每次请求都要渲染) | 低(CDN 分发) | 低(CDN + 按需渲染) |
| 适用场景 | 后台管理系统、SPA | 动态内容多、SEO 要求高 | 内容不常变化的页面 | 内容会变化但不要求实时 |
二、CSR(客户端渲染)
2.1 工作原理
用户请求 → 服务器返回空 HTML + JS → 浏览器下载 JS → JS 执行渲染页面 |
<!-- 服务器返回的 HTML(几乎为空) --> |
2.2 优缺点
// 优点 |
2.3 代表框架
- React(CRA / Vite)
- Vue(Vue CLI / Vite)
- Angular
三、SSR(服务端渲染)
3.1 工作原理
用户请求 → 服务器执行 JS,生成完整 HTML → 返回给浏览器 |
// Next.js 中的 SSR 示例(getServerSideProps) |
3.2 优缺点
// 优点 |
3.3 Hydrate(水合)过程
1. 服务器返回完整 HTML → 浏览器立即显示(可看到内容) |
// React 水合示例 |
3.4 SSR 框架
| 框架 | 说明 |
|---|---|
| Next.js | React SSR 框架(最流行) |
| Nuxt.js | Vue SSR 框架 |
| Remix | 全栈框架(基于 React) |
| SvelteKit | Svelte SSR 框架 |
| Angular Universal | Angular SSR |
四、SSG(静态站点生成)
4.1 工作原理
build 时 → 服务器执行所有页面的渲染 → 生成静态 HTML 文件
用户请求 → CDN 直接返回静态文件(无需服务器渲染)
SSG 的核心是在构建阶段(Build Time)预渲染页面。在运行构建命令(如 next build 或 nuxt generate)时,框架会抓取数据并生成包含真实 DOM 结构的静态 HTML、CSS 和 JS 文件。在生产环境中,这些文件会被部署到 CDN 上,用户访问时直接由边缘节点返回静态文件,无需服务器实时渲染。
// Next.js 中的 SSG 示例(getStaticProps) |
4.2 动态路由的 SSG
// pages/blog/[id].js |
4.3 fallback 选项
export async function getStaticPaths() { |
4.4 优缺点
// 优点 |
4.5 SSG 适用场景
- 博客 / 文档站
- 产品展示页
- 营销落地页
- 个人主页
- 内容不常变化的官网
五、ISR(增量静态再生)
5.1 工作原理
build 时 → 生成静态 HTML(同 SSG) |
// Next.js 中的 ISR 示例 |
5.2 revalidate 工作流程
时间线: |
5.3 优缺点
// 优点 |
5.4 ISR 适用场景
- 电商产品列表(价格、库存变化)
- 新闻聚合页
- 用户生成内容的展示页
- 需要 SEO 的动态内容页
六、四种方案决策树
需要 SSR / SSG / ISR 吗? |
七、Next.js 中的混用示例
// 同一个 Next.js 项目中,不同页面可以用不同方案 |
八、性能指标对比
| 指标 | CSR | SSR | SSG | ISR |
|---|---|---|---|---|
| FCP(首次内容绘制) | 差(1-3s) | 好(<1s) | 最好(<0.5s) | 好(<1s) |
| LCP(最大内容绘制) | 差 | 好 | 最好 | 好 |
| TTI(可交互时间) | 差 | 中等 | 最好 | 好 |
| TTFB(首字节时间) | 好 | 中等 | 最好 | 好 |
| CLS(累积布局偏移) | 中等 | 好 | 最好 | 好 |
九、Nuxt.js 中的对应方案
// Nuxt 3 |
十、高频问题
Q1: SSR 和 SSG 的区别?
SSR:每次请求都实时渲染 HTML,内容永远是最新的 |
Q2: ISR 的 revalidate 如何工作?
1. build 时生成静态页面 |
Q3: SSR 为什么需要 Hydrate?
1. 服务器渲染的 HTML 只有内容,没有交互能力 |
Q4: SSR 的 TTFB 为什么比 CSR 差?
CSR:服务器直接返回静态 HTML(很快) |
Q5: SSG 如何处理动态路由?
方法1:预渲染所有路径(getStaticPaths 返回所有可能的参数) |
Q6: ISR 和 SSR 如何选择?
ISR:内容不是实时的,但性能好(CDN 分发) |
Q7: React 18 流式 SSR 是什么?
// 传统 SSR:等所有组件渲染完再返回 |
Q8: 水合不匹配(Hydration Mismatch)是什么?
// 服务器渲染 |
Q9: 如何避免 SSR 中的内存泄漏?
// 问题:每次请求都创建新的 React 树 |
Q10: SSG 的 Incremental Static Regeneration(ISR)和 On-Demand Revalidation 区别?
ISR(基于时间): |
// On-Demand Revalidation 示例 |
十一、框架生态对比
| 框架 | SSR | SSG | ISR | 流式 SSR |
|---|---|---|---|---|
| Next.js | ✅ | ✅ | ✅ | ✅(React 18) |
| Nuxt 3 | ✅ | ✅ | ✅(routeRules) | ✅ |
| Remix | ✅ | ❌(嵌套路由) | ❌ | ❌ |
| Astro | ✅(Islands) | ✅ | ❌ | ❌ |
| SvelteKit | ✅ | ✅ | ❌ | ❌ |
| Gatsby | ❌(已转向 SSR) | ✅ | ❌ | ❌ |
十二、一句话总结
| 方案 | 一句话 |
|---|---|
| CSR | 浏览器下载 JS 后渲染,适合后台系统 |
| SSR | 服务器每次请求都渲染,适合动态+SEO |
| SSG | 构建时一次性生成,适合不常变化的静态内容 |
| ISR | SSG + 按需更新,兼顾性能和内容新鲜度 |
| Streaming SSR | 流式返回,边渲染边输出,减少 TTFB |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 搬码人’s Blog!
评论






