寻求Express.js中间件:实时压缩静态文件并内存缓存方案
Node.js静态文件实时压缩+内存缓存方案
针对你的需求,推荐使用express-static-gzip这个开箱即用的库,它能直接处理./static目录下的静态文件,支持实时压缩并将结果缓存到内存中,完全适配你的场景。
核心特性
- 自动根据请求头
Accept-Encoding返回对应压缩格式(gzip/brotli) - 实时压缩未预压缩的文件,压缩结果直接存入内存缓存
- 支持自定义缓存大小、有效期等参数
- 无需额外配置复杂的缓存逻辑,开箱即用
快速实现步骤
- 安装依赖
npm install express express-static-gzip
- 配置服务代码
const express = require('express'); const expressStaticGzip = require('express-static-gzip'); const app = express(); // 配置静态文件服务,开启压缩与内存缓存 app.use('/', expressStaticGzip('./static', { enableBrotli: true, // 启用更高效的brotli压缩 orderPreference: ['br', 'gzip'], // 优先返回brotli压缩结果 cache: { maxSize: 100 * 1024 * 1024, // 内存缓存上限100MB maxAge: 86400000 // 缓存有效期1天(可根据需求调整) } })); app.listen(3000, () => { console.log('服务启动在3000端口'); });
替代方案(自定义程度更高)
如果需要更灵活的控制,可以用compression中间件搭配lru-cache手动实现:
- 安装依赖
npm install express compression lru-cache
- 自定义缓存逻辑
const express = require('express'); const compression = require('compression'); const LRU = require('lru-cache'); const fs = require('fs').promises; const path = require('path'); const app = express(); const cache = new LRU({ max: 100 * 1024 * 1024 }); // 100MB缓存上限 // 自定义压缩缓存中间件 async function compressCached(req, res, next) { const filePath = path.join('./static', req.url); const cacheKey = `${filePath}-${req.headers['accept-encoding']}`; // 检查内存缓存 const cachedData = cache.get(cacheKey); if (cachedData) { res.setHeader('Content-Encoding', cachedData.encoding); res.setHeader('Content-Type', cachedData.contentType); return res.send(cachedData.data); } try { // 读取原文件 const data = await fs.readFile(filePath); // 根据请求头选择压缩方式 const acceptEncoding = req.headers['accept-encoding'] || ''; let compressedData, encoding; if (acceptEncoding.includes('br')) { compressedData = require('zlib').brotliCompressSync(data); encoding = 'br'; } else if (acceptEncoding.includes('gzip')) { compressedData = require('zlib').gzipSync(data); encoding = 'gzip'; } else { return res.send(data); } // 存入内存缓存 const contentType = require('mime-types').lookup(filePath) || 'application/octet-stream'; cache.set(cacheKey, { data: compressedData, encoding, contentType }); // 返回压缩结果 res.setHeader('Content-Encoding', encoding); res.setHeader('Content-Type', contentType); res.send(compressedData); } catch (err) { next(err); } } app.use(compressCached); app.listen(3000, () => { console.log('服务启动在3000端口'); });
不过第一种方案(express-static-gzip)更省心,完全满足开箱即用的需求,推荐优先使用。
内容的提问来源于stack exchange,提问作者xue zhang
相关产品推荐
相关产品推荐

