缓存预热是通过提前调用 memoize 返回的缓存函数,将高频参数的结果存入其闭包内 Map 缓存中;需确保函数实例常驻、选择精准参数、配合时机策略与清理机制。

高阶函数本身不直接“预热”缓存,但它能构造出具备缓存能力且支持主动触发计算的函数——真正的缓存预热,是调用这个缓存函数时人为提前传入关键参数,让结果落进闭包维护的私有缓存中。
缓存预热器的本质不是新工具,而是对 memoize 函数的主动调用
所谓“预热”,就是在用户还没点击、还没输入、还没触发某操作前,你已预料到某些输入大概率会出现(比如首页默认筛选条件、常用搜索词、固定 ID 的详情请求),于是提前执行一次缓存函数:
- 你写的 memoize(fn) 返回一个新函数,它内部通过闭包持有
cache对象 - 这个新函数既能响应用户实时调用,也能被你在任意时机手动调用,比如在组件挂载、页面初始化、或空闲时段
- 只要那次手动调用完成,对应参数的结果就已存在
cache中,后续真实用户调用就是毫秒级返回
一个可预热的 memoize 实现(支持多参数 + Map 键安全)
相比只用 JSON.stringify 的简单版本,这个更健壮,适合预热场景:
function memoize(fn) {
const cache = new Map();
<p>return function(...args) {
// 用 Object.is 比较数组/对象参数(需扁平化处理),此处简化为字符串键
const key = JSON.stringify(args);</p><pre class="brush:php;toolbar:false;">if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;}; }
使用示例:
const heavyCalc = (a, b) => {
console.log('正在执行耗时计算...');
return a * b + Math.sin(a);
};
<p>const cachedCalc = memoize(heavyCalc);</p><p>// ✅ 预热:用户还没操作,你就先算好 (2, 3) 和 (5, 7)
cachedCalc(2, 3); // 输出 log,结果进 cache
cachedCalc(5, 7); // 输出 log,结果进 cache</p><p>// ✅ 用户真正调用时,无 log,直接返回
console.log(cachedCalc(2, 3)); // 瞬间输出结果,不打印 log预热时机与策略建议
预热不是越多越好,关键在“准”和“轻”:
- 在路由切换后或组件 mounted 时预热:比如进入商品列表页,立即预热最常点的前 3 个商品 ID 的详情数据
- 利用 requestIdleCallback 做低优先级预热:避免阻塞主线程,适合加载非首屏但高频的备选数据
- 限制预热参数数量:缓存空间有限,预热 5 个确定会用的值,比盲目预热 50 个模糊猜测的值更安全
-
配合清理机制:如果预热结果可能过期(如价格、库存),需搭配 TTL 或手动
cache.delete(key)
注意闭包带来的隐含约束
预热生效的前提,是那个 memoize 返回的函数实例持续存活——也就是闭包没被回收:
- 不要把
cachedCalc定义在函数内又不保留引用,否则每次调用都新建一个闭包,预热白做 - 推荐将预热后的缓存函数作为模块级变量或 React useMemo 缓存的值,确保单例
- 若用 class,可将它放在实例属性上:
this.cachedFn = memoize(fn),并在 constructor 或 componentDidMount 中预热

















