数据缓存
cache 函数可以让你缓存数据获取或计算的结果。
基本用法
import { cache } from '@modern-js/runtime/cache';
import { fetchUserData } from './api';
const getUser = cache(fetchUserData);
const loader = async () => {
const user = await getUser(user); // 函数入参发生变化时,函数会重新执行
return {
user,
};
};
参数
fn: 需要缓存的数据获取或计算的函数
options(可选): 缓存配置
tag: 用于标识缓存的标签,可以基于这个标签使缓存失效
maxAge: 缓存的有效期 (毫秒)
revalidate: 重新验证缓存的时间窗口(毫秒),与 HTTP Cache-Control 的 stale-while-revalidate 功能一致
options 参数的类型如下:
interface CacheOptions {
tag?: string | string[];
maxAge?: number;
revalidate?: number;
}
返回值
cache 函数会返回一个新的函数,该函数有缓存的能力,多次调用该函数,不会重复执行 fn 函数。
使用范围
与 react 的 cache 函数只能在 server component 组件中使用不同,
EdenX 提供的 cache 函数可以在任意的前端或服务端的代码中使用。
详细用法
无 options 参数
当无 options 参数传入时,主要可以用于 SSR 项目,缓存的生命周期是单次 ssr 渲染的请求,如可以在多个 data loader 中调用同一个 cachedFn 时,不会重复执行 cachedFn 函数。这样可以在不同的 data loader 中共享数据,同时避免重复的请求,EdenX 会在每次收到服务端请求时,重新执行 fn 函数。
INFO
无 options 参数时,可以看作是 react cache 函数的替代品,可以在任意服务端代码中使用(比如可以在 SSR 项目的 data loader 中),不局限于 server component。
import { cache } from '@modern-js/runtime/cache';
import { fetchUserData } from './api';
const getUser = cache(fetchUserData);
const loader = async () => {
const user = await getUser();
return {
user,
};
};
有 options 参数
maxAge 参数
每次计算完成后,框架会记录写入缓存的时间,当再次调用该函数时,会根据 maxAge 参数判断缓存是否过期,如果过期,则重新执行 fn 函数,否则返回缓存的数据。
import { cache, CacheTime } from '@modern-js/runtime/cache';
const getDashboardStats = cache(
async () => {
return await fetchComplexStatistics();
},
{
maxAge: CacheTime.MINUTE * 2, // 在 2 分钟内调用该函数会返回缓存的数据
}
);
revalidate 参数
revalidate 参数用于设置缓存过期后,重新验证缓存的时间窗口,可以和 maxAge 参数一起使用,类似与 HTTP Cache-Control 的 stale-while-revalidate 模式。
如以下示例,在缓存未过期的 2分钟内,如果调用 getDashboardStats 函数,会返回缓存的数据,如果缓存过期,2分到3分钟内,收到的请求会先返回旧数据,然后后台会重新请求数据,并更新缓存。
import { cache, CacheTime } from '@modern-js/runtime/cache';
const getDashboardStats = cache(
async () => {
return await fetchComplexStatistics();
},
{
maxAge: CacheTime.MINUTE * 2,
revalidate: CacheTime.MINUTE * 1,
}
);
tag 参数
tag 参数用于标识缓存的标签,可以传入一个字符串或字符串数组,可以基于这个标签使缓存失效,多个缓存函数可以使用一个标签。
import { cache, revalidateTag } from '@modern-js/runtime/cache';
const getDashboardStats = cache(
async () => {
return await fetchDashboardStats();
},
{
tag: 'dashboard',
}
);
const getComplexStatistics = cache(
async () => {
return await fetchComplexStatistics();
},
{
tag: 'dashboard',
}
);
revalidateTag('dashboard-stats'); // 会使 getDashboardStats 函数和 getComplexStatistics 函数的缓存都失效
存储
目前不管是客户端还是服务端,缓存都存储在内存中,默认情况下所有缓存函数共享的存储上限是 1GB,当达到存储上限后,使用 LRU 算法移除旧的缓存。
INFO
考虑到 cache 函数缓存的结果内容不会很大,所以目前默认都存储在内存中
可以通过 configureCache 函数指定缓存的存储上限:
import { configureCache, CacheSize } from '@modern-js/runtime/cache';
configureCache({
maxSize: CacheSize.MB * 10, // 10MB
});