Next.js 系列之的SSG、SSR、ISR、CSR 的详细介绍和区别

前端153 次阅读13 分钟

Next.js 提供了多种渲染策略(SSG、SSR、ISR、CSR),每种策略适用于不同的场景。以下是它们的核心区别、实现方式及最佳实践:


1. SSG(Static Site Generation,静态生成)

核心特点

  • 生成时机:在构建时(next build)生成静态 HTML。
  • 数据获取:通过 getStaticProps 获取数据,支持预渲染所有页面。
  • 适用场景:内容不经常变化的页面(如博客、文档、营销页)。
  • 优点:加载最快、SEO 友好、CDN 缓存友好。
  • 缺点:无法实时更新内容,需重新构建才能更新。

实现代码

// pages/blog/[slug].js
export async function getStaticPaths() {
  // 预生成所有可能的路径(如博客文章列表)
  const posts = await fetch('<https://api.example.com/posts>');
  return {
    paths: posts.map(post => ({ params: { slug: post.slug } })),
    fallback: false, // 未预生成的路径返回 404
  };
}

export async function getStaticProps({ params }) {
  // 根据 slug 获取单篇文章内容
  const post = await fetch(`https://api.example.com/posts/${params.slug}`);
  return { props: { post } };
}

export default function BlogPost({ post }) {
  return <article>{post.content}</article>;
}


2. SSR(Server-Side Rendering,服务端渲染)

核心特点

  • 生成时机:每次页面请求时在服务端动态生成 HTML。
  • 数据获取:通过 getServerSideProps 在请求时获取最新数据。
  • 适用场景:需要实时数据的页面(如用户仪表盘、实时股价)。
  • 优点:内容始终最新,支持个性化渲染(如基于 Cookie 的权限验证)。
  • 缺点:TTFB(首字节时间)较慢,服务端压力大。

实现代码

// pages/dashboard.js
export async function getServerSideProps(context) {
  // 从请求中获取 Cookie 或用户信息
  const user = await getUserFromCookie(context.req.cookies);
  const data = await fetch(`https://api.example.com/dashboard?user=${user.id}`);
  return { props: { data } };
}

export default function Dashboard({ data }) {
  return <div>{data.stats}</div>;
}


3. ISR(Incremental Static Regeneration,增量静态再生)

核心特点

  • 生成时机:SSG 的扩展,允许在运行时按需重新生成静态页面。
  • 数据获取:在 getStaticProps 中设置 revalidate 参数(秒),触发条件: • 初次访问时生成静态页面。 • 后续访问时,若超过 revalidate 时间,后台重新生成页面。
  • 适用场景:内容更新频率适中的页面(如电商产品页、新闻列表)。
  • 优点:兼具 SSG 的速度和 SSR 的更新能力,减轻服务端压力。
  • 缺点:再生成期间用户可能看到旧数据。

实现代码

// pages/products/[id].js
export async function getStaticPaths() {
  return { paths: [], fallback: 'blocking' }; // 动态生成所有路径
}

export async function getStaticProps({ params }) {
  const product = await fetch(`https://api.example.com/products/${params.id}`);
  return {
    props: { product },
    revalidate: 3600, // 每 1 小时重新验证一次
  };
}

export default function Product({ product }) {
  return <div>{product.name}</div>;
}


4. CSR(Client-Side Rendering,客户端渲染)

核心特点

  • 生成时机:在客户端浏览器中通过 JavaScript 渲染内容。
  • 数据获取:通过 useEffectSWR 在组件挂载后获取数据。
  • 适用场景:交互性强、无需 SEO 的页面(如用户后台、管理面板)。
  • 优点:减少服务端负载,支持动态交互。
  • 缺点:首屏加载慢,SEO 不友好,依赖客户端 JavaScript。

实现代码

// pages/profile.js
import { useEffect, useState } from 'react';

export default function Profile() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // 组件挂载后获取用户数据
    fetch('/api/user')
      .then(res => res.json())
      .then(data => setUser(data));
  }, []);

  if (!user) return <div>Loading...</div>;
  return <div>{user.name}</div>;
}


5. 对比表格

特性 SSG SSR ISR CSR
生成时机 构建时 每次请求时 构建时 + 按需再生 客户端运行时
数据实时性 低(需重新构建) 高(实时) 中等(可配置更新间隔) 高(动态获取)
SEO 支持 ✅ 最佳 ✅ 良好 ✅ 良好 ❌ 差(需额外处理)
首屏加载速度 ⚡️ 最快 ⏳ 较慢(依赖服务端) ⚡️ 快(缓存优先) ⏳ 慢(需加载 JS)
适用场景 静态内容 实时数据 频繁更新但非实时内容 交互复杂、无需 SEO
服务端压力

6. 混合使用策略

Next.js 允许在同一个项目中灵活组合多种渲染方式: • SSG + CSR:首屏静态渲染,交互部分客户端加载(如博客的评论模块)。 • SSR + ISR:动态页面初次 SSR,后续通过 ISR 缓存(如新闻详情页)。 • App Router 优化:在 app 目录中,使用 React Server Components 减少客户端 JS 体积。

示例:混合 SSG 和 CSR

// pages/index.js(SSG 主页面)
export async function getStaticProps() {
  const posts = await fetch('<https://api.example.com/posts>');
  return { props: { posts } };
}

export default function Home({ posts }) {
  // 主内容静态生成,评论模块客户端渲染
  return (
    <div>
      {posts.map(post => <Post key={post.id} {...post} />)}
      <ClientOnly>
        <Comments />
      </ClientOnly>
    </div>
  );
}

// 客户端组件(仅在浏览器加载)
function Comments() {
  const [comments, setComments] = useState([]);
  useEffect(() => {
    fetch('/api/comments').then(res => res.json()).then(setComments);
  }, []);
  return <div>{comments.map(comment => <div>{comment.text}</div>)}</div>;
}


7. 选择策略的决策树

  1. 是否需要 SEO? • ✅ 是 → 使用 SSG、SSR 或 ISR。 • ❌ 否 → 使用 CSR。
  2. 数据是否频繁更新? • ✅ 是 → 使用 SSR 或 ISR。 • ❌ 否 → 使用 SSG。
  3. 是否有个性化内容? • ✅ 是 → 使用 SSR。 • ❌ 否 → 使用 SSG 或 ISR。

总结

  • SSG:优先用于内容稳定、SEO 关键的页面。
  • SSR:用于实时数据或个性化内容。
  • ISR:平衡速度与更新频率,适合大规模内容站点。
  • CSR:用于交互复杂、无需 SEO 的功能模块。
  • 混合使用:结合不同策略,最大化性能与功能灵活性。

系列文章

Next.js 系列之客户端组件(Client Components)和服务端组件(Server Components)的区别

Next.js 系列之Serverless(无服务器架构)介绍

Next.js 系列之 app router 和 page router 的区别

Next.js 系列之的SSG、SSR、ISR、CSR 的详细介绍和区别