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

"你是谁?"

"我是静态的你。"

"你骗人,我明明看到你每次刷新都在变!"

"......那是我服务器的灵魂在响应。"

------节选自《React:组件的思辨》


🧭 前言:静态与动态,时间与空间的选择

在 Next.js 的世界里,你面对的不仅是页面和组件,还有一个哲学命题:

这个页面该在构建时生成,还是每次访问时实时生成?

是预知未来般一次性构建好所有页面(SSG),

还是像一位热情厨师,每次来客都现做一碗热面(SSR)?

让我们揭开这两个 API 的面纱:


📦 什么是 SSG(Static Site Generation)?

"我一次生成所有页面,你来不来,我都在 CDN 上等你。"

SSG 的核心逻辑在于:页面在构建时就完成了生成,生成后的 HTML 会被部署到边缘节点,访问速度极快。

🍱 使用场景:

  • 博客文章
  • 产品详情页(不常变化)
  • 文档类网站

🧬 核心 API:getStaticProps

javascript 复制代码
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

javascript 复制代码
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]

javascript 复制代码
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

javascript 复制代码
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 让你作为这个选择的编剧,而不是苦力。


📚 延伸阅读

相关推荐
我是苏苏18 分钟前
Web开发:C#通过ProcessStartInfo动态调用执行Python脚本
java·服务器·前端
无羡仙38 分钟前
Vue插槽
前端·vue.js
哈__1 小时前
React Native 鸿蒙跨平台开发:PixelRatio 像素适配
javascript·react native·react.js
用户6387994773051 小时前
每组件(Per-Component)与集中式(Centralized)i18n
前端·javascript
SsunmdayKT1 小时前
React + Ts eslint配置
前端
开始学java1 小时前
useEffect 空依赖 + 定时器 = 闭包陷阱?count 永远停在 1 的坑我踩透了
前端
zerosrat1 小时前
从零实现 React Native(2): 跨平台支持
前端·react native
狗哥哥2 小时前
🔥 Vue 3 项目深度优化之旅:从 787KB 到极致性能
前端·vue.js
青莲8432 小时前
RecyclerView 完全指南
android·前端·面试
青莲8432 小时前
Android WebView 混合开发完整指南
android·前端·面试