缓存和重新验证
Caching
缓存是存储数据以减少向服务器发出的请求数量的过程。Next.js 为个别数据请求提供了内置的数据缓存, 为您提供对缓存行为的精细控制。
fetch 请求
默认情况下,Next.js15 中fetch请求不被缓存。
为了缓存单个fetch请求, 您可以使用cache: 'force-cache'选项:
fetch("https://...", { cache: "force-cache" });
数据请求库 和 ORMs
为了将特定的请求缓存到数据库或 ORM, 您可以使用 unstable_cache API:
import { getUser } from "./data";
import { unstable_cache } from "next/cache";
const getCachedUser = unstable_cache(
async (id) => getUser(id),
["my-app-user"]
);
export default async function Component({ userID }) {
const user = await getCachedUser(userID);
return user;
}
重新验证数据
重新验证是清除数据缓存和重新获取最新数据的过程。当您的数据发生变化并且您想确保显示最新信息,同时,仍然获益于 静态渲染速度时,这是非常有用的。
可以通过两种方式重新验证缓存数据:
- 基于时间的重新验证: 经过某段时间过后自动重新验证数据。这对于变化不频繁且新鲜度不那么重要的数据很有用。
- 按需重新验证: 根据事件(例如表单提交)来手动重新验证书。按需验证可以使用基于标签的或基于路径的方法一次性重新验证数据组。这对于您想要确保尽快展示最新数据非常有用。(例如:当您的无头 CMS 中内容更新时).
Time-based revalidation
为了每个一段时间重新验证数据, 您可以使用fetch的next.revalidate选项来设置一个资源的缓存周期(以秒为单位)。
fetch("https://...", { next: { revalidate: 3600 } }); // revalidate at most every hour
或者, 为了重新验证路由段中的所有请求,您可以使用段配置选项。
export const revalidate = 3600; // revalidate at most every hour
您需要知道:
- 如果在一个静态渲染路由中您有多个 fetch 请求, 并且每个请求都有不同的重新验证频率。则将对所有请求使用时间最短的那个。
- 对于动态渲染的路由,每个
fetch请求将会被单独重新验证。- 为了节省服务器资源, 我们推荐尽可能设置较长的重新验证时间。例如,1 小时而不是 1 秒。如果您需要实时数据,请考虑选择动态渲染 或客户端数据请求。
On-demand revalidation
可以使用 revalidatePath 和 revalidateTag APIs 按需重新验证数据。
在 Server Actions 或 Route Handler中使用 revalidatePath来为特定的路由重新验证数据:
import { revalidatePath } from "next/cache";
export async function createPost() {
// Mutate data
revalidatePath("/posts");
}
import { revalidatePath } from "next/cache";
export async function createPost() {
// Mutate data
revalidatePath("/posts");
}
使用revalidateTag来重新验证跨路由的fetch请求。
- 当使用
fetch时, 您可以选择使用一个或多个标签来标记缓存条目。 - 然后, 您可以调用
revalidateTag来重新验证与该标签相关的所有条目。
例如,下列的fetch请求添加了缓存标签collection:
export default async function Page() {
const res = await fetch("https://...", { next: { tags: ["collection"] } });
const data = await res.json();
// ...
}
export default async function Page() {
const res = await fetch("https://...", { next: { tags: ["collection"] } });
const data = await res.json();
// ...
}
然后,您可以通过调用revalidateTag来重新验证标记为collection的fetch call :
"use server";
import { revalidateTag } from "next/cache";
export async function action() {
revalidateTag("collection");
}
"use server";
import { revalidateTag } from "next/cache";
export async function action() {
revalidateTag("collection");
}
了解按需重新验证的工作原理。
错误处理和重新验证
如果在尝试重新验证数据时抛出了错误,则上一次成功生成的数据将继续从缓存中提供。在下一个后续请求中,next .js 将重新验证数据。