一、先说结论:渲染方式不是选的,是“推导出来的”
有人问:
👉「这个页面用 SSG 还是 SSR?」
但在 Next.js(尤其是 App Router)里,正确的问题其实是:
👉「这个页面的数据在什么时候才能确定?」
数据何时确定,渲染方式就是什么。
二、四种渲染方式的本质差异
我用一句话总结它们的核心区别:
| 渲染方式 | 本质问题 |
|---|---|
| SSG | 构建时能否拿到完整数据 |
| SSR | 是否必须每次请求都最新 |
| ISR | 是否允许“过期一段时间” |
| ISR | 是否必须由用户行为触发 |
注意:CSR 不是服务器渲染策略,而是客户端行为
三、SSG:最理想的状态(能用就用)
我的判断标准
一个页面满足下面条件,我一定用 SSG:
- 数据在 build 阶段就能确定
- 数据变化频率低
- SEO 或首屏性能重要 常见例子
- 博客文章
- 产品介绍页
- 文档页面
Next.js 中为什么它会“自动变成 SSG”?
因为:
- 不 fetch 数据
- 或 fetch 使用默认缓存策略
fetch(url); // 默认就是长期缓存
不是你“选择了 SSG”,而是你没有破坏静态条件。
四、SSR:不是高级,而是代价最高
我什么时候会用 SSR?
只有一个理由:
比如:
❗这个页面在任何时刻都必须是最新的
- 用户实时状态
- 强依赖请求上下文(cookie / header) 在 App Router 中,SSR 的真实开关
fetch(url, { cache: 'no-store' });
这行代码意味着:
- 不缓存
- 每次请求都重新执行
- 服务端压力直线上升 👉 所以 SSR 是兜底方案,不是默认方案
五、ISR:实际项目中最常用的折中方案
在真实项目中,有些人用得最多的反而是 ISR。
为什么?
因为大多数页面:
- 不需要“秒级实时”
- 但也不能“永远不更新”
两种典型 ISR 用法
1️⃣ 定时更新(时间驱动)
export const revalidate = 60;
适合:
- 新闻列表
- 排行榜
- 聚合内容
2️⃣ 按需更新(事件驱动)
revalidatePath('/posts');
适合:
- 提交表单后
- 后台修改内容后
这是 SSG + 手动刷新缓存,不是 SSR
六、CSR:它从来不是“渲染方案”
这是很多人最容易混淆的点。
正确认知 CSR
- CSR ≠ 页面类型
- CSR = 浏览器里跑的 JavaScript
在 Next.js 中:
所有 CSR 都依赖 SSG / SSR 提供初始 HTML
我在项目里怎么用 CSR?
- 搜索框
- 筛选
- 分页
- 弹窗
- 状态切换
'use client'; useEffect(() => { fetch('/api/data').then(...) }, []);
👉 CSR 用来 补充交互,而不是承担首屏渲染
最后编辑于 2025-12-29 21:03:03