简述 Node.js 中的缓存机制
Node.js 在多个层面都内置或支持缓存机制,从模块加载、HTTP 响应到外部数据库结果都可以走缓存路径,以减少 I/O 与重复计算。
来源整理自:vue3js.cn 面试官系列
1. 核心结论
- Node.js 主要提供三类缓存:模块缓存(
require.cache)、内存缓存(开发者自维护的对象/Map)、HTTP 缓存(协议层 Cache-Control/ETag/Last-Modified)。 - 缓存的目标都是"减少对原始数据源的访问",但失效策略与适用场景各不相同。
2. 背景知识
(1)缓存的基本概念
缓存是一种机制,用于临时存储数据,以减少对原始数据源的访问,从而提高系统性能和响应速度。在 Node.js 中,不同的缓存机制针对不同的应用场景发挥作用。
(2)Node.js 的特点
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,具有单线程、事件驱动、非阻塞 I/O 等特点。这些特点使得缓存机制在 Node.js 中尤为重要,可有效提升性能。
3. 解析
(1)模块缓存
工作原理:Node.js 在首次加载模块时,会将该模块的导出对象存储在 require.cache 对象中。当再次使用 require 函数加载相同模块时,会直接从缓存中获取该模块的导出对象,而不是重新执行模块代码。
作用:避免重复加载和执行模块代码,节省时间和资源,提高模块加载速度。
示例代码:
// module.js
module.exports = { value: 42 };
// main.js
const module1 = require('./module.js');
const module2 = require('./module.js');
console.log(module1 === module2); // 输出: true
(2)内存缓存
工作原理:开发者可以手动在内存中创建对象来存储数据,作为简单的缓存。例如使用普通的 JavaScript 对象,将数据存储在其中,并通过键值对的方式进行读写操作。
作用:对于一些频繁使用且不经常变化的数据,可以存储在内存缓存中,减少对数据库或其他外部资源的访问,提高数据获取速度。
示例代码:
const cache = new Map();
function getData(key) {
if (cache.has(key)) return cache.get(key);
// 模拟从数据源获取数据
const data = `Data for ${key}`;
cache.set(key, data);
return data;
}
(3)HTTP 缓存
工作原理:在 Node.js 中使用 HTTP 服务器时,可以利用 HTTP 协议的缓存机制,如 Cache-Control、ETag、Last-Modified 等头部信息。客户端在请求资源时,服务器可以根据这些头部信息判断客户端缓存的资源是否有效,从而决定是否返回新的资源。
Expires/Cache-Control:绝对时间/过期时间(强缓存,返回 200 from disk/memory)。Last-Modified/ETag:协商缓存(304 Not Modified)。
作用:减少客户端和服务器之间的数据传输,降低服务器负载,提高用户体验。
示例代码:
const http = require('node:http');
const fs = require('node:fs');
http.createServer((req, res) => {
fs.readFile('file.txt', (err, data) => {
if (err) { res.statusCode = 500; return res.end('Error'); }
res.setHeader('Cache-Control', 'public, max-age=3600');
res.end(data);
});
}).listen(3000);
4. 常见误区
(1)忽视模块缓存
误区:每次使用模块时都认为会重新加载和执行模块代码,未意识到模块缓存的存在。
纠正:了解 require.cache 对象,知道 Node.js 会自动缓存已加载的模块,避免不必要的重复加载。
(2)内存缓存管理不当
误区:在使用内存缓存时,不考虑缓存数据的过期和清理,导致内存占用过高。
纠正:为缓存数据设置合理的过期时间,并定期清理过期数据,以避免内存泄漏。
(3)滥用 HTTP 缓存
误区:对所有资源都设置相同的缓存策略,不考虑资源的更新频率和特性。
纠正:根据资源的实际情况,合理设置 Cache-Control、ETag 等头部信息,以达到最佳的缓存效果。



