🚀 Next.js 的“双面人生”:SSG 与 SSR 的哲学对话

16 阅读4分钟

“你是谁?”
“我是静态的你。”
“你骗人,我明明看到你每次刷新都在变!”
“……那是我服务器的灵魂在响应。”

——节选自《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 让你作为这个选择的编剧,而不是苦力。


📚 延伸阅读