ISR(Incremental Static Regeneration)是 Next.js 的一个强大特性, 它结合了静态生成的性能和动态渲染的新鲜度。
工作原理:
ISR 使用了 stale-while-revalidate 策略:
Stale(陈旧)
返回缓存的页面(即使可能过期)→ 用户看到页面很快
While(同时)
在后台重新生成页面 → 不阻塞用户请求
Revalidate(重新验证)
生成完成后更新缓存 → 下一个用户看到新内容
标题:
ISR 测试页面
描述:
这个页面每 30 秒会重新生成一次
渲染时间:
2025-12-27T07:41:47.588Z
✅ 在 30 秒内保持不变,之后会更新
随机值:
217
✅ 每次重新验证时都会变化
重新验证间隔:
30 秒
✅ export const revalidate = 30;
pnpm build在构建日志中,这个页面会显示为:○ /rendering-test/isr (30 seconds)
○ 表示静态生成,括号中是 revalidate 时间
1. 记录当前渲染时间
2. 在 30 秒内刷新多次 → 时间不变(使用缓存)
3. 等待 30 秒后刷新 → 仍返回旧页面(stale)
4. 再次刷新 → 看到新时间(revalidate 完成)
在构建时和重新验证时,会打印 [ISR] 日志
注意:不是每次访问都打印,只在重新生成时打印
打开 Network 面板,查看响应头:Cache-Control: s-maxage=30, stale-while-revalidate
⚠️ 注意:用户 3 看到的是旧页面(A),因为新页面(B)还在生成中。 这确保了用户始终能快速获得响应。
// app/blog/[slug]/page.tsx
// 配置 ISR:每 60 秒重新验证
export const revalidate = 60;
export default async function BlogPost({ params }) {
// 这个数据获取在构建时和重新验证时执行
const post = await fetchPost(params.slug);
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
<time>{post.updatedAt}</time>
</article>
);
}
// 动态路由需要 generateStaticParams
export async function generateStaticParams() {
const posts = await fetchAllPosts();
return posts.map((post) => ({ slug: post.slug }));
}
// 或者使用 fetch 的 revalidate 选项
async function fetchPost(slug) {
const res = await fetch(`https://api.example.com/posts/${slug}`, {
next: { revalidate: 60 }, // 60 秒后重新验证
});
return res.json();
}页面中的所有 fetch 都使用这个 revalidate 时间
单个 fetch 请求的 revalidate 时间
组合配置,确保静态生成 + ISR