Nextjs支持的哪些缓存
AI摘要: 本文详细介绍了Next.js在不同层面支持的缓存机制,包括API层面的响应头控制、Fetch函数的缓存策略、Cache函数实现的函数级缓存、页面级别的ISR缓存以及跨实例的KV分布式缓存。重点解析了各层级的技术实现方式和适用场景,如通过Cache-Control头部设置浏览器/CDN缓存时效性、force-cache强制边缘缓存特性、react.cache高阶函数优化重复计算逻辑等关键技术点。
在Vercel中,nextjs为了支持severless特性,支持了各种层面的缓存能力。
API层面
Nextjs支持通过在/app/api
目录下,通过route.ts
对外开放一个api接口,那么接口级别的缓存方式为:
export async function GET() {
xxx
return NextResponse.json(
{ categories: formattedCategories },
{
status: 200,
headers: {
"Cache-Control": "public, max-age=60, stale-while-revalidate=30"
}
}
);
}
-
max-age=60: 通常设置为60s,表示浏览器/Edge Cache缓存60s
-
stale-while-revalidate=30:国企之后,继续返回旧数据,同时后台异步更新
-
缓存可以在Edge/CDN层生效,减少数据库压力
Fetch函数缓存
Nextjs中经常使用Fetch来从其他接口(内部或者外部)来获取数据,也可以进行缓存:
export async function GET() {
const res = await fetch("https://api.example.com/data", { cache: "force-cache" });
const data = await res.json();
return NextResponse.json(data);
}
-
cache的取值:[“no-store”, “force-cache”, “default”]
-
主要作用在内部Fetch,而不是控制最终HTTP响应,配合revalidate可以实现ISR
Cache缓存
Nextjs还提供了Cache函数,支持对函数级别缓存,避免重复执行函数逻辑
import { cache } from "react";
const getCategories = cache(async function () {
console.log("fetching categories");
const categories = await prisma.resource.groupBy({
by: ["category"],
_count: { id: true },
});
return categories;
});
export async function GET() {
const categories = await getCategories();
return NextResponse.json({ categories });
}
-
缓存范围为同一个server实例内部重复调用,直接返回缓存结果,不再重复执行函数体
-
Serverless实例冷启动之后,缓存会丢失
-
比较适用一些频繁调用的函数(如查询数据库,计算密集型逻辑)
页面级别缓存
还有一个更顶层一点的页面级别缓存,一般用于ISR,通过export const revalidate = xxx;实现
不过export const revalidate = xxx似乎不支持计算表达式,必须计算出具体的重新验证的时间数值,比较不智能
KV缓存
之前所有的都是同一个Serverless实例内部缓存,如果跨实例,那么需要一个类似redis的分布式缓存中间件,比如Vercel KV