1. Incremental Static Regeneration
- 方法:在
getStaticProps
函数中使用 revalidate
选项。例如:
export async function getStaticProps() {
const res = await fetch('https://example.com/api/blog-post');
const data = await res.json();
return {
props: {
blogPost: data
},
revalidate: 60 // 每60秒重新生成一次页面
};
}
- 优点:
- 无需手动干预,Next.js 会按照设定的时间间隔自动重新生成页面,保证内容在一定时间内是最新的。
- 对于数据更新频率不高,但又需要保证相对实时性的场景非常适用,减少了服务器资源的消耗。
- 缺点:
- 无法保证数据的绝对实时性,因为有重新验证的时间间隔,在间隔内数据更新用户不会立刻看到。
- 如果重新验证频率设置过高,可能会对服务器资源造成一定压力,尤其是在高流量网站中。
2. Stale - While - Revalidate Pattern
- 方法:结合前端缓存和后台重新验证。首先,在客户端展示缓存的旧数据,同时在后台发起请求获取最新数据并更新缓存。例如,在前端使用
SWR
库(常用于 Next.js 中处理数据请求和缓存):
import useSWR from'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
function BlogPost() {
const { data, error } = useSWR('/api/blog-post', fetcher);
if (error) return <div>Failed to load</div>;
if (!data) return <div>Loading...</div>;
return (
<div>
<h1>{data.title}</h1>
<p>{data.content}</p>
</div>
);
}
- 优点:
- 用户能立即看到页面内容,因为先展示缓存数据,提升了用户体验。
- 后台在用户浏览时自动更新数据,使得后续页面刷新或重新访问能看到最新内容。
- 缺点:
- 实现相对复杂,需要结合前端缓存库如
SWR
等进行合理配置和管理。
- 初始展示的可能是较旧的数据,对于实时性要求极高的场景不太适用。
3. Manual Revalidation
- 方法:通过 API 端点手动触发页面重新生成。例如,在更新博客文章的 API 逻辑中,添加调用 Next.js 提供的
revalidatePath
函数(需使用 Next.js 12+):
import { revalidatePath } from 'next/cache';
export default async function handler(req, res) {
// 更新博客文章的逻辑
const updatedPost = await updateBlogPost(req.body);
// 重新验证博客文章页面路径
revalidatePath('/blog/[slug]', 'page');
res.status(200).json(updatedPost);
}
- 优点:
- 能保证数据更新后立即反映到页面上,实现绝对实时性。
- 灵活可控,可在数据更新的关键逻辑处手动触发,适用于对数据一致性要求高的场景。
- 缺点:
- 需要在后端更新逻辑中添加额外代码,增加了开发和维护成本。
- 如果触发频率过高,可能对服务器资源造成较大压力,尤其是在高并发更新场景下。