Node.js传输120MB以上JSON文件生产环境加载慢如何优化
性能优化方案
现有代码核心问题
你当前的实现存在两个明显的性能损耗点:
- 使用
require加载JSON文件是同步阻塞操作,会先把120MB的JSON全量转为JS对象缓存在内存中,后续res.json又会把JS对象重新序列化为JSON字符串,两次转换+全量内存占用会大幅增加服务端处理耗时,且require的缓存机制会导致你每日更新的JSON文件无法被实时读取,必须重启服务才能拿到新数据。 - 没有开启传输压缩,120MB的纯文本裸传对生产环境带宽压力极大,是耗时过高的核心原因。
可落地优化方案
1. 替换为流式传输,跳过重复转换
直接流式读取原始JSON文件,直接输出到响应,不需要全量加载到内存,也不需要两次格式转换:
const fs = require('fs') const path = require('path') router.get('/getData',(req, res) => { res.setHeader('Content-Type', 'application/json') // 流式读取文件直接输出到响应 const jsonStream = fs.createReadStream(path.join(__dirname, './newDataJson.json')) jsonStream.pipe(res) // 异常处理 jsonStream.on('error', err => { res.status(500).end('数据读取失败') }) });
2. 强制开启生产环境传输压缩
JSON属于高压缩率文本,开启gzip或Brotli压缩后,120MB的JSON通常可以压缩到10~20MB,传输耗时直接下降一个量级:
- 如果直接用Node.js提供服务,可引入
compression中间件:const compression = require('compression') const express = require('express') const app = express() // 放在所有路由最前面开启压缩 app.use(compression({ filter: (req, res) => req.headers['accept-encoding'] && /json/.test(res.getHeader('Content-Type')) })) - 如果生产环境用Nginx做反向代理,直接在Nginx配置中开启gzip/Brotli压缩,压缩性能比Node.js自带更高。
3. 客户端处理优化
axios默认会等待全量响应接收完成后再统一解析JSON,120MB数据的解析也会占用大量时间,可以开启流式响应模式,边接收边解析:
const fetchNewData = async () => { const { data } = await axios.get(`/api/getData/`, { // 开启流式响应 responseType: 'stream' }) // 搭配stream-json等流式解析库,可以实现边接收边处理数据 }
4. 进阶可选优化
- 每日生成JSON时直接预压缩为.gz格式存储到磁盘,请求时直接返回预压缩的文件,省去每次请求实时压缩的CPU开销。
- 接口添加CDN缓存,因为是每日更新的静态数据,缓存有效期可设置为23小时,用户访问直接走CDN节点无需回源,速度更快。
- 如果业务场景允许,将大JSON拆分为多个小分片接口,客户端并行请求多个分片,比单请求串行传输速度提升数倍。
内容的提问来源于stack exchange,提问作者Logicx Mend
相关产品推荐
相关产品推荐

