CSR vs SSR vs SSG vs ISR:怎么选?边界是什么?(体验 + 成本 + 一致性)
一句话结论:渲染策略不是“越 SSR 越高级”,而是 体验(首屏/SEO/交互)× 成本(开发/运行/发布)× 一致性(更新/缓存/个性化) 的权衡:
- CSR:开发/部署最简单,但首屏与 SEO 需要额外治理
- SSR:首屏可见更快、SEO 友好,但把复杂度带到服务端(并发、缓存、稳定性)
- SSG:性能与稳定性最强,但数据更新与个性化受限
- ISR:在 SSG 的收益上引入“可控更新”,但一致性与缓存策略必须设计清楚
0. 先对齐一个关键误区:SSR ≠ 可交互
无论 CSR/SSR/SSG/ISR,最终都需要 hydration 才能交互(除非你的页面几乎无交互)。
- SSR/SSG/ISR 解决的是:更快拿到可见 HTML
- Hydration 解决的是:把 React 事件/状态接管到 DOM 上
关联阅读(生产事故高发):Hydration mismatch:
./01-hydration-mismatch.md
1. 四种策略的“核心差异”是什么?
你可以用一句话记忆:
- CSR:HTML 壳 + JS 拉数据后再渲染(客户端决定内容)
- SSR:每次请求在服务端渲染 HTML(请求时决定内容)
- SSG:构建时预渲染 HTML(构建时决定内容)
- ISR:以 SSG 为主,但允许按时间/事件重生成(构建与请求之间的折中)
infographic list-grid-badge-card
data
title 渲染策略速览(你在优化什么)
items
- label CSR
desc 最简单;首屏与 SEO 需要额外治理
icon mdi:monitor
- label SSR
desc 首屏/SEO 更好;服务端复杂度上升
icon mdi:server
- label SSG
desc 性能/稳定性最强;更新与个性化受限
icon mdi:file-document-outline
- label ISR
desc 在 SSG 上引入可控更新;一致性策略更关键
icon mdi:refresh
2. 选型维度:体验 × 成本 × 一致性
2.1 体验(用户感知)
关注:
- 首屏可见:TTFB/FCP/LCP
- 导航体验:切页是否闪屏、是否能预取
- 交互响应:INP 是否被 hydration/JS 执行拖垮
- SEO:是否需要让爬虫直接看到内容
倾向:
- 强 SEO:SSG/ISR/SSR
- 强交互 SPA:CSR(但要做性能与骨架治理)或 Next App Router 的混合模式
2.2 成本(工程与运行)
关注:
- 开发复杂度:数据获取边界、错误/加载边界
- 运维复杂度:服务端并发、缓存、容灾、灰度
- 成本:服务端计算与带宽
倾向:
- 想最省事:CSR/SSG
- 能接受服务端复杂度换体验:SSR
2.3 一致性(更新与缓存)
关注:
- 数据多久更新一次?能接受“最终一致”吗?
- 是否是用户态数据(个性化、权限、购物车)?
- 是否存在多层缓存(CDN、框架缓存、客户端缓存)?
倾向:
- 公共内容(资讯、文档):SSG/ISR
- 强一致用户态:SSR(或强动态 no-store)+ 客户端缓存策略
关联阅读(Next 上线事故常见根因):Next 缓存/重验证与一致性:
./04-nextjs-cache-revalidate-consistency-online-not-updating.md
3. 常见业务场景的推荐
3.1 登录后后台(B 端 / 管理台)
特点:
- SEO 不重要
- 强交互、复杂表格/筛选
- 用户态数据多
推荐:
- CSR(Vite SPA) + TanStack Query
- 或 Next App Router,但把用户态数据设为强动态(避免缓存一致性坑)
3.2 内容站(资讯、博客、文档)
特点:
- SEO 重要
- 内容更新频率可控
推荐:
- SSG(静态生成)
- 内容需要按分钟/小时更新:ISR + tag/time revalidate
3.3 商品详情/营销页(C 端)
特点:
- SEO 重要
- 首屏体验重要
- 数据有一定更新频率
推荐:
- ISR 或 SSR(视更新与个性化程度)
- 关键:把缓存一致性策略写清楚(否则“线上怎么不更新”)
3.4 既要 SEO 又要强交互的混合应用
推荐:
- Next App Router 的“混合模式”:
- 页面级:RSC/SSR/ISR(首屏)
- 交互级:Client Components + TanStack Query(局部交互)
关键约束:
- 同一数据域不要被两套缓存系统各自管理(Next fetch cache vs React Query)
4. 反模式(踩一次就会懂)
- 为了 SSR 而 SSR
- 结果:服务端复杂度暴涨、错误与监控体系跟不上、收益不明显
- ISR 没有设计 revalidate 规则
- 结果:要么永远不更新,要么更新不一致(多层缓存打架)
- 用户态数据走了 cache/静态化
- 结果:A 用户看到 B 用户数据(严重事故),或权限穿透
- 忽视 hydration 的成本
- 结果:HTML 很快到,但页面很久不能点(INP 变差)
5. Checklist(落地自检)
- 这类页面是否需要 SEO?(爬虫是否必须看到真实内容)
- 你优化的目标是什么?TTFB/FCP/LCP 还是 INP/交互?
- 数据更新频率与一致性要求是什么?(强一致/最终一致)
- 是否存在用户态/权限数据?是否会被缓存污染?
- 是否明确了缓存层(CDN / Next Data Cache / Route Cache / Client Cache)?
- 是否能在 dev 与 prod 环境复现一致性问题?(缓存策略是否一致)
关联阅读
- Hydration mismatch 排查:
./01-hydration-mismatch.md - Next 缓存与重验证:
./04-nextjs-cache-revalidate-consistency-online-not-updating.md - 路由与 URL state(对渲染策略的影响):
../10-routing-and-navigation/01-routing-and-url-state-mental-model.md