6月2日 23:15
Next.js SSR、SSG 和 ISR 有什么区别?怎么选?
SSR、SSG、ISR 是三种不同的页面渲染策略,区别在于 HTML 什么时候生成。选哪个取决于数据的更新频率和页面的实时性要求。
三种策略对比
| 策略 | HTML 生成时机 | 适合场景 | 性能 |
|---|---|---|---|
| SSG | 构建时 | 博客、文档、营销页 | 最快(CDN 缓存) |
| SSR | 每次请求时 | 仪表盘、个人主页 | 中等(服务端计算) |
| ISR | 构建时 + 定时更新 | 商品列表、新闻 | 接近 SSG 的速度 |
SSG(Static Site Generation)
构建时生成 HTML,部署后不变化。速度最快——CDN 直接返回静态文件,零服务端计算。
tsx// App Router 默认就是 SSG // 没有 dynamic 数据获取的页面自动静态生成 export default function AboutPage() { return <h1>关于我们</h1>; } // 带数据的 SSG:构建时获取 async function BlogList() { const posts = await db.post.findMany(); // 构建时执行 return posts.map(p => <article key={p.id}>{p.title}</article>); }
局限:数据变化后需要重新构建部署。适合不常变的内容。
SSR(Server-Side Rendering)
每次请求时生成 HTML。数据始终最新,但每次请求都有服务端计算开销。
tsx// App Router: 使用动态数据获取自动触发 SSR async function Dashboard() { const stats = await fetch('https://api.example.com/stats', { cache: 'no-store' // 不缓存,每次请求重新获取 }).then(r => r.json()); return <div>{stats.users} 用户</div>; }
cache: 'no-store' 告诉 Next.js 这个请求不能缓存,必须每次执行。适合实时数据。
ISR(Incremental Static Regeneration)
SSG 的升级版——静态生成 HTML,但后台定时重新生成。兼具 SSG 的速度和数据的新鲜度。
tsxasync function ProductList() { const products = await fetch('https://api.example.com/products', { next: { revalidate: 3600 } // 每 3600 秒(1 小时)重新验证 }).then(r => r.json()); return products.map(p => <div key={p.id}>{p.name}</div>); }
ISR 的工作流程:
- 第一个用户请求 → 返回缓存的静态 HTML(快)
- 后台检查 revalidate 时间是否到期
- 到期后重新生成 HTML,替换旧缓存
- 下一个用户请求 → 返回新生成的 HTML
关键点:用户永远看到的是缓存的页面(快),后台异步更新。最坏情况数据延迟 revalidate 秒。
怎么选
选 SSG:内容几乎不变(文档、博客、营销页)
选 ISR:内容定期更新(商品列表、新闻、排行榜),能接受短暂延迟
选 SSR:内容必须实时(仪表盘、用户个人页、搜索结果)
常见错误:所有页面都用 SSR。大部分页面用 ISR 就够了——1-5 分钟的数据延迟用户感知不到,但性能提升显著。
App Router 中的 revalidate 策略
tsx// 定时重新验证(ISR) fetch(url, { next: { revalidate: 60 } }); // 60 秒 // 按需重新验证:修改数据后手动触发 import { revalidateTag, revalidatePath } from 'next/cache'; // 在 Server Action 里触发 async function updateProduct(formData: FormData) { await db.product.update({ ... }); revalidateTag('products'); // 刷新所有 products 标记的缓存 revalidatePath('/products'); // 刷新 /products 页面 }
按需重新验证(On-Demand Revalidation)比定时更精准——数据变了立即刷新,没变就不浪费资源。