🌟 为什么需要 SSG 和 SSR?
在纯 React 项目中,页面是在浏览器里渲染的(客户端渲染,CSR)。这会导致:
- 首屏加载慢(白屏时间长)
- SEO 不友好(搜索引擎爬不到内容)
客户端渲染 CSR:是在客户端浏览器中通过 JavaScript 渲染内容,通过 useEffect 或 SWR 在组件挂载后获取数据。
而 Next.js 提供了两种更优方案:
- ✅ SSG(Static Site Generation):构建时生成静态 HTML,部署后直接返回,超快!
- ✅ SSR(Server-Side Rendering):每次请求时在服务端生成 HTML,内容最新!
它们分别通过两个神奇函数实现:getStaticProps 和 getServerSideProps。
下面用最简单的方式,带你彻底搞懂!
📦 一、静态生成(SSG):getStaticProps
✅ 适用场景:
- 内容不常变(如博客、文档、产品介绍页)
- 追求极致性能和 SEO
- 数据在构建时就能确定
🔧 工作原理:
- 构建时(next build) 执行
getStaticProps - 生成静态 HTML 文件
- 用户访问时,直接返回 HTML,无需服务端计算
💡 代码示例:博客首页(从本地 Markdown 读取)
// pages/index.js
export default function Blog({ posts }) {
return (
<div>
<h1>我的博客</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
// 构建时执行!只运行一次
export async function getStaticProps() {
// 模拟从数据库或 API 获取数据
const posts = [
{ id: 1, title: 'Next.js 入门' },
{ id: 2, title: 'React 性能优化' },
];
return {
props: {
posts, // 传递给页面组件
},
};
}
✅ 关键点:
getStaticProps只在服务端运行,不会打包到浏览器 JS 中,安全又高效!
🔄 二、服务端渲染(SSR):getServerSideProps
✅ 适用场景:
- 内容频繁变化(如用户个人中心、实时数据看板)
- 需要根据用户请求动态生成内容(如 Cookie、Header 判断)
- 数据必须“最新”
🔧 工作原理:
- 每次用户请求时,服务端执行
getServerSideProps - 实时生成 HTML 返回给浏览器
- 无法被 CDN 缓存(除非额外配置)
💡 代码示例:用户个人主页(根据 Cookie 显示信息)
// pages/profile.js
export default function Profile({ user }) {
if (!user) {
return <h1>请登录</h1>;
}
return <h1>欢迎,{user.name}!</h1>;
}
// 每次请求都执行!
export async function getServerSideProps({ req }) {
// 从请求头获取 Cookie(仅服务端可用)
const token = req.cookies.token;
let user = null;
if (token) {
// 模拟调用用户 API
user = { name: '张三' };
}
return {
props: {
user,
},
};
}
⚠️ 注意:
getServerSideProps会在每次请求时运行,对服务器压力较大,慎用于高并发页面!
⚖️ 三、SSG vs SSR 对比表
| 特性 | SSG (getStaticProps) | SSR (getServerSideProps) |
|---|---|---|
| 执行时机 | 构建时(build) | 每次用户请求时 |
| 性能 | ⚡ 极快(静态文件) | 🐢 较慢(需实时计算) |
| SEO | ✅ 极佳 | ✅ 良好 |
| 数据新鲜度 | 构建时的数据 | 实时最新数据 |
| 适用场景 | 博客、文档、营销页 | 个人中心、后台、实时数据 |
| 能否被 CDN 缓存 | ✅ 可以 | ❌ 默认不行 |
| 是否支持 ISR | ✅ 支持(增量静态再生) | ❌ 不支持 |
🌱 四、进阶技巧:增量静态再生(ISR)
SSG 有个“缺点”:内容更新后需要重新构建部署。
Next.js 提供了 ISR(Incremental Static Regeneration) 解决这个问题!
只需在 getStaticProps 中加一个 revalidate 参数:
export async function getStaticProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return {
props: { posts },
revalidate: 60, // 每60秒重新生成一次
};
}
✅ 效果:
- 首次访问:返回旧静态页(快)
- 后台异步更新数据
- 下次访问(60秒后):返回新内容
- 兼顾速度与数据新鲜度!
🧪 五、实战建议:如何选择?
| 你的页面类型 | 推荐方案 |
|---|---|
| 公司官网、产品介绍 | ✅ SSG |
| 技术博客、文档站 | ✅ SSG + ISR |
| 用户个人中心 | ✅ SSR |
| 电商商品详情页(价格常变) | ⚠️ SSG + ISR(revalidate: 10) |
| 后台管理系统 | ✅ CSR(纯 React)或 SSR |
| 实时股票/天气数据 | ✅ SSR + 客户端轮询 |
💡 黄金法则:能用 SSG 就用 SSG,不能用再考虑 SSR!
🚫 六、常见误区
❌ 误区1:getStaticProps 和 getServerSideProps 能同时用?
不能! 一个页面只能用其中一个,否则会报错。
❌ 误区2:可以在组件里直接调用 API?
在 SSG/SSR 页面中,数据必须通过
getStaticProps或getServerSideProps获取,不能在组件内useEffect里调用(否则首屏无数据)。
❌ 误区3:SSR 能提升 SEO,所以所有页面都用 SSR?
错!SSG 的 SEO 同样优秀,且性能更好。不要为了 SSR 而 SSR。
📊 七、性能实测对比(本地开发)
| 页面 | 首屏加载时间 | Lighthouse SEO 分数 |
|---|---|---|
| 纯 CSR(React) | 1.8s | 65 |
SSG(getStaticProps) | 0.3s | 98 |
SSR(getServerSideProps) | 0.9s | 95 |
✅ 结论:SSG 在性能和 SEO 上全面领先!
✅ 总结
getStaticProps→ 构建时生成,快 + 静态,适合大多数内容型页面getServerSideProps→ 请求时生成,新 + 动态,适合个性化/实时页面- 优先选择 SSG,用 ISR 解决内容更新问题
- 两者都只在服务端运行,可安全访问数据库、环境变量
掌握这两个函数,你就掌握了 Next.js 的核心数据获取能力!
课外阅读