从0死磕全栈之next.js 静态生成(SSG) vs 服务端渲染(SSR):`getStaticProps` 和 `getServerSideProps` 一

183 阅读4分钟

🌟 为什么需要 SSG 和 SSR?

在纯 React 项目中,页面是在浏览器里渲染的(客户端渲染,CSR)。这会导致:

  • 首屏加载慢(白屏时间长)
  • SEO 不友好(搜索引擎爬不到内容)

客户端渲染 CSR:是在客户端浏览器中通过 JavaScript 渲染内容,通过 useEffect 或 SWR 在组件挂载后获取数据。

Next.js 提供了两种更优方案

  • SSG(Static Site Generation):构建时生成静态 HTML,部署后直接返回,超快!
  • SSR(Server-Side Rendering):每次请求时在服务端生成 HTML,内容最新!

它们分别通过两个神奇函数实现:getStaticPropsgetServerSideProps

下面用最简单的方式,带你彻底搞懂!


📦 一、静态生成(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:getStaticPropsgetServerSideProps 能同时用?

不能! 一个页面只能用其中一个,否则会报错。

❌ 误区2:可以在组件里直接调用 API?

在 SSG/SSR 页面中,数据必须通过 getStaticPropsgetServerSideProps 获取,不能在组件内 useEffect 里调用(否则首屏无数据)。

❌ 误区3:SSR 能提升 SEO,所以所有页面都用 SSR?

错!SSG 的 SEO 同样优秀,且性能更好。不要为了 SSR 而 SSR


📊 七、性能实测对比(本地开发)

页面首屏加载时间Lighthouse SEO 分数
纯 CSR(React)1.8s65
SSG(getStaticProps0.3s98
SSR(getServerSideProps0.9s95

结论:SSG 在性能和 SEO 上全面领先!


✅ 总结

  • getStaticProps → 构建时生成,快 + 静态,适合大多数内容型页面
  • getServerSideProps → 请求时生成,新 + 动态,适合个性化/实时页面
  • 优先选择 SSG,用 ISR 解决内容更新问题
  • 两者都只在服务端运行,可安全访问数据库、环境变量

掌握这两个函数,你就掌握了 Next.js 的核心数据获取能力!


课外阅读

从0死磕全栈第6天:React useEffect副作用起了大作用之实现购物车功能