Next.js 预渲染完全指南:SSG vs SSR,看完秒懂!

如何让你的 Next.js 应用秒开?预渲染机制是关键!本文将带你彻底搞懂两种预渲染方式的区别和实战应用。

前言:为什么需要预渲染?

大家好,我是前端大鱼。最近在自己的项目中深度使用了 Next.js,不得不说它的预渲染能力真的太香了!

想象一下这样的场景:用户打开你的网站,几乎瞬间看到完整内容,而不是先看一个 loading 动画等待几秒钟。这就是预渲染带来的魔力!

与传统 React SPA 相比,Next.js 的预渲染让 SEO 再也不是问题,搜索引擎爬虫可以直接看到完整的页面内容。今天我就带大家彻底搞懂 Next.js 的预渲染机制。

一、预渲染的两种方式

1.1 静态生成(SSG)- 推荐首选

构建时生成页面,直接输出 HTML 文件扔到 CDN 上。

jsx 复制代码
export default function HomePage({ posts }) {
  return (
    <div>
      <h1>博客首页</h1>
      {posts.map(post => (
        <Article key={post.id} post={post} />
      ))}
    </div>
  );
}

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  return {
    props: { posts }, // 传递给页面组件
    revalidate: 60,   // 60秒后可重新生成(ISR)
  };
}

优点

  • ⚡️ 速度极致:CDN 直接返回静态文件,快就一个字
  • 💰 成本极低:不需要服务器实时计算
  • 🔍 SEO 友好:内容完整可抓取
  • 🚀 高并发:轻松应对流量高峰

适用场景

  • 博客、文档站
  • 电商商品列表页
  • 公司官网
  • 营销落地页

1.2 服务器端渲染(SSR)- 按需使用

每次请求时生成页面,适合个性化内容。

jsx 复制代码
export default function UserProfile({ user }) {
  return (
    <div>
      <h1>欢迎, {user.name}!</h1>
      <p>这是你的个人主页</p>
    </div>
  );
}

// 每次请求都运行
export async function getServerSideProps(context) {
  // 获取 cookies 验证用户
  const token = context.req.cookies.auth;
  const user = await fetchUser(token);

  if (!user) {
    return {
      redirect: {
        destination: '/login', // 未登录跳转
        permanent: false,
      },
    };
  }

  return {
    props: { user }, // 传递给页面
  };
}

优点

  • 📊 数据实时:每次都是最新数据
  • 👤 个性化:基于用户请求定制内容
  • 🔐 安全性:敏感数据处理在服务端

适用场景

  • 用户仪表盘
  • 实时数据页面
  • 需要权限验证的页面

二、动态路由的预渲染技巧

对于动态路由(如 /posts/[id].js),需要 getStaticPaths 配合:

jsx 复制代码
// pages/posts/[id].js
export default function PostDetail({ post }) {
  return <Article content={post.content} />;
}

// 告诉 Next.js 哪些路径需要预渲染
export async function getStaticPaths() {
  const posts = await fetch('https://api.example.com/posts');
  
  const paths = posts.map(post => ({
    params: { id: post.id.toString() },
  }));

  return {
    paths,
    fallback: 'blocking', // 重要参数!
  };
}

// 获取具体数据
export async function getStaticProps({ params }) {
  const post = await fetchPost(params.id);
  
  return {
    props: { post },
    revalidate: 3600, // 每小时更新一次
  };
}

fallback 参数详解

  • false:只渲染指定路径,其他 404
  • true:先返回降级页面,后台生成新页面
  • 'blocking':等待生成完成再返回,用户体验更好

三、实战选择指南

3.1 如何选择?

根据你的业务场景来定:

用 SSG(静态生成)如果:

  • 内容不经常变化
  • 需要极致的性能
  • 页面是公开的,不需要用户验证

用 SSR(服务器端渲染)如果:

  • 数据实时性要求高
  • 内容高度个性化
  • 需要访问请求上下文(如 cookies)

3.2 性能对比

指标 SSG SSR
加载速度 ⭐⭐⭐⭐⭐ ⭐⭐⭐
SEO 支持 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
实时性 ⭐⭐(可配 ISR) ⭐⭐⭐⭐⭐
服务器压力 ⭐⭐⭐⭐⭐ ⭐⭐⭐
开发复杂度 ⭐⭐⭐ ⭐⭐⭐⭐

3.3 混合使用案例

在实际项目中,我们通常混合使用:

jsx 复制代码
// 主页:SSG + 客户端数据获取
export default function Home({ initialData }) {
  const [realTimeData, setRealTimeData] = useState(null);
  
  // 静态部分优先展示
  // 动态部分客户端获取
  useEffect(() => {
    fetchRealTimeData().then(setRealTimeData);
  }, []);

  return (
    <div>
      <StaticContent data={initialData} />
      {realTimeData && <DynamicContent data={realTimeData} />}
    </div>
  );
}

export async function getStaticProps() {
  const initialData = await fetchInitialData();
  return { props: { initialData }, revalidate: 60 };
}

四、最佳实践与坑点避雷

4.1 一定要知道的坑

坑1:getStaticPaths 的 fallback 选择

jsx 复制代码
// 错误:大量动态页面时用 false
return { paths: [], fallback: false };

// 正确:用 blocking 或 true
return { paths: [], fallback: 'blocking' };

坑2:API 路由不匹配

jsx 复制代码
// 错误:在 getStaticProps 里调用了内部 API
const res = await fetch('http://localhost:3000/api/posts');

// 正确:直接导入函数或调用外部 API
const posts = await getPostsFromDB();

4.2 性能优化技巧

1. 使用 ISR(增量静态再生)

jsx 复制代码
export async function getStaticProps() {
  return {
    props: { /* ... */ },
    revalidate: 60, // 60秒后可重新生成
  };
}

2. 优化图片加载

jsx 复制代码
import Image from 'next/image';

export default function Product({ product }) {
  return (
    <div>
      <Image
        src={product.image}
        alt={product.name}
        width={500}
        height={300}
        placeholder="blur" // 占位优化
      />
    </div>
  );
}

3. 代码分割自动完成 Next.js 自动按页面做代码分割,无需额外配置!

五、总结

Next.js 的预渲染机制是其最大亮点之一,正确使用能让你的应用性能飞起:

  1. SSG 用于静态内容 - 极致性能,CDN 友好
  2. SSR 用于动态内容 - 实时数据,个性化强
  3. 混合使用更灵活 - 根据不同场景选择方案
  4. ISR 平衡两者 - 静态生成 + 定时更新

掌握了这些,你就能充分发挥 Next.js 的优势,打造出高性能的 React 应用!


互动时间:大家在用 Next.js 时遇到过哪些预渲染的问题?欢迎在评论区分享你的经验和疑问!

关注公众号" 大前端历险记",掌握更多前端开发干货姿势!

相关推荐
BBB努力学习程序设计12 小时前
CSS3渐变:用代码描绘色彩的流动之美
前端·html
冰暮流星12 小时前
css之动画
前端·css
jump68012 小时前
axios
前端
spionbo12 小时前
前端解构赋值避坑指南基础到高阶深度解析技巧
前端
用户40993225021212 小时前
Vue响应式声明的API差异、底层原理与常见陷阱你都搞懂了吗
前端·ai编程·trae
开发者小天12 小时前
React中的componentWillUnmount 使用
前端·javascript·vue.js·react.js
永远的个初学者13 小时前
图片优化 上传图片压缩 npm包支持vue(react)框架开源插件 支持在线与本地
前端·vue.js·react.js
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ13 小时前
npm i / npm install 卡死不动解决方法
前端·npm·node.js
Kratzdisteln13 小时前
【Cursor _RubicsCube Diary 1】Node.js;npm;Vite
前端·npm·node.js
杰克尼13 小时前
vue_day04
前端·javascript·vue.js