数据缓存
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
});