“你是谁?”
“我是静态的你。”
“你骗人,我明明看到你每次刷新都在变!”
“……那是我服务器的灵魂在响应。”
——节选自《React:组件的思辨》
🧭 前言:静态与动态,时间与空间的选择
在 Next.js 的世界里,你面对的不仅是页面和组件,还有一个哲学命题:
这个页面该在构建时生成,还是每次访问时实时生成?
是预知未来般一次性构建好所有页面(SSG),
还是像一位热情厨师,每次来客都现做一碗热面(SSR)?
让我们揭开这两个 API 的面纱:
📦 什么是 SSG(Static Site Generation)?
“我一次生成所有页面,你来不来,我都在 CDN 上等你。”
SSG 的核心逻辑在于:页面在构建时就完成了生成,生成后的 HTML 会被部署到边缘节点,访问速度极快。
🍱 使用场景:
- 博客文章
- 产品详情页(不常变化)
- 文档类网站
🧬 核心 API:getStaticProps
export async function getStaticProps(context) {
const res = await fetch('https://api.example.com/posts')
const data = await res.json()
return {
props: {
posts: data,
},
}
}
这段代码的意思就是:
“Next.js,在你 build 的时候,请访问这个 API,然后把结果塞进页面里,这样访问的时候不用再请求后端啦。”
✅ 优势:
- 极致性能(CDN 加持)
- 可 SEO(因为 HTML 是现成的)
- 成本低
❗ 缺点:
- 不实时,数据更新需要重新构建
- 页面数量太多时构建时间会变长
🍲 什么是 SSR(Server Side Rendering)?
“每次你点开我,我都会从服务器现抓数据,做出热腾腾的 HTML。”
SSR 就像一个动态厨房:你来了我做,不浪费资源,也能确保你吃到的是最新鲜的数据。
🥣 使用场景:
- 登录后的用户信息页
- 股票价格、天气等实时数据页
- 电商网站首页
🔌 核心 API:getServerSideProps
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/user-info')
const user = await res.json()
return {
props: {
user,
},
}
}
这段代码的意思就是:
“每当有人访问我,先去服务器厨房抓点数据回来,再让浏览器看到页面。”
✅ 优势:
- 数据始终是最新的
- 可根据请求头(如 Cookie)做个性化页面
❗ 缺点:
- 每次访问都要服务器生成 HTML,压力山大
- 慢一点,没法用 CDN 静态缓存
🧠 本质上的差异:构建时 vs 请求时
特性 | getStaticProps (SSG) | getServerSideProps (SSR) |
---|---|---|
运行时机 | 构建阶段 | 每次请求 |
页面是否缓存 | 是(CDN) | 否 |
SEO 友好 | 是 | 是 |
是否个性化 | 否 | 是 |
性能表现 | 极速 | 一般 |
适合页面数量 | 少量 or 可分页 | 不限 |
🧪 实验场景:一个博客平台
博客文章页(/posts/[id]
)
export async function getStaticProps(context) {
const post = await fetchPost(context.params.id);
return {
props: { post },
revalidate: 60, // ISR,60秒重新生成一次
};
}
你说它是静态的,其实它每隔 60 秒偷偷更新一次。
这就是传说中的:ISR(Incremental Static Regeneration)
用户中心页(/me
)
export async function getServerSideProps(context) {
const user = await fetchUser(context.req.cookies.token);
return {
props: { user },
};
}
每个用户看到的页面都不同。你说它能静态化,那就离谱。
⚙️ 技术栈小贴士
⛓️ 通常会组合使用的:
getStaticProps
+getStaticPaths
:生成多个静态页面(如所有文章)getServerSideProps
+ 中间件鉴权:做登录跳转、个性化推荐等- ISR:最强大的增量再生魔法
🧙♂️ 它们背后的原理简单解析
getStaticProps
:在 构建阶段运行 →next build
时调用 → HTML + JSON 写入.next
静态目录getServerSideProps
:在 Node.js 服务器运行 → 每次请求触发 → 实时拿数据 → 返回 React 组件的 props- 两者都会在页面加载时作为 初始 props 注入,前端无感知是否是静态或动态生成。
💡 最佳实践建议
如果你希望... | 建议使用 |
---|---|
页面超快打开 | getStaticProps |
页面随时更新 | getServerSideProps |
页面定期更新 + 快速 | getStaticProps + revalidate (ISR) |
页面根据用户定制 | getServerSideProps |
页面数据在客户端拿即可 | 根本不用这两个 API,直接用 useEffect() ! |
🎭 后记:你可以选择时间,也可以选择实时
Next.js 并没有给你一个非此即彼的选择,而是:
“你想站在时间的前方生成页面?那就 SSG;
你想在用户眼前生成内容?那就 SSR。”
是提前准备所有内容,还是及时回应每个访问者?
Next.js 让你作为这个选择的编剧,而不是苦力。