JSON 是文本格式,原生开销大于二进制格式,可以从压缩、精简结构、传输策略、解析优化、数据设计、替代方案取舍几个维度提升交换效率。
1. 数据内容精简(减少原始 JSON 体积)
去除空格、换行、缩进
不要格式化美化输出,输出压缩 JSON(minify),去掉多余空格换行。
json
// 压缩前(可读性好,体积大)
{
"name": "test",
"age": 18
}
// 压缩后(传输用)
{"name":"test","age":18}
缩短键名
业务传输时可以使用短 key,例如
u代替userName,接收方再映射还原;注意不要牺牲可读性,适合对内接口。避免冗余字段
只传输需要的字段,不要全量导出对象;过滤
null、空字符串、空数组,减少无效数据。数值不使用字符串包裹
数字、布尔直接用 JSON 原生类型,不要写成字符串
"age":"18",既增大体积又增加解析转换开销。
2. 传输层压缩(收益最高)
HTTP 接口开启 gzip /deflate/br (Brotli) 压缩。
JSON 文本压缩率非常高,通常可以压缩到原大小 1/3~1/5;
Nginx、SpringBoot、Apache 都可一键开启;
大 JSON 文件落地后也可以保存为
.json.gz,传输时直接传压缩包。
注意:小数据(几十字节)压缩收益很低,甚至压缩后更大,可做阈值判断,大于阈值再开启压缩。
3. JSON 结构设计优化
优先数组结构,避免嵌套对象
嵌套层级越深,解析开销越大。
差:
{"data":{"list":[{"id":1}]}}优:
[{"id":1}]数组批量传输,减少请求次数
尽量批量传多条记录,不要一条数据一次 JSON 请求,减少网络握手开销。
避免深层嵌套,控制 JSON 嵌套深度,深层嵌套会提升解析 CPU、内存开销。
大列表不要内嵌完整对象,可采用列存储思路
json
// 普通对象数组
[{"id":1,"name":"a"},{"id":2,"name":"b"}]
// 列式JSON,适合大批量同构数据,体积更小
{"id":[1,2],"name":["a","b"]}
4. 解析与序列化性能优化
选用高性能 JSON 库
Java:Jackson > Gson;Go:encoding/json;避免低效的手动字符串拼接 JSON(极易出错还慢)。
关闭不需要的序列化特性
如不输出日期格式化字符串,尽量输出时间戳(数字);忽略未知字段。
流式解析,不要一次性全加载到内存
处理超大 JSON 文件(GB 级):使用 JSON 流式解析(Jackson Streaming、JsonLines),边读边处理,不把整个 JSON 加载进内存,防止 OOM。
JSON Lines (NDJSON)
大批量行式数据交换推荐 .jsonl(每行一条独立 JSON)
plaintext
{"id":1,"name":"a"}
{"id":2,"name":"b"}
优势:
不需要把全部数据包裹在一个大数组;
可以流式逐行解析;
支持断点续处理,部分出错不影响全部。
5. 网络与交互策略
分页 / 分片传输,超大数据集拆分多个小 JSON,避免单次超大报文。
条件查询、增量同步:只传输变更数据,不用全量导出全部 JSON。例如带上版本号 / 时间戳,只传增量变更 JSON。
合理使用 HTTP 缓存,不变的 JSON 可以缓存,避免重复传输。
6. 当 JSON 仍然不够快:二进制备选
当极致性能场景,JSON 文本仍然有开销,可以选用 JSON 衍生二进制格式:
MessagePack:JSON 的二进制等价,数据模型和 JSON 完全一致,体积更小,适合程序间交换;
ProtocolBuffers(Protobuf):强 schema 二进制,性能最高,需要预定义 proto;
BSON:MongoDB 使用,适合文档存储;
注意:JSON 优势是人类可读、通用,异构语言调试方便;二进制格式效率高,但可读性差。
总结:优先级排序
开启 Brotli/gzip 压缩 → 收益最大,改动最小
JSON 压缩输出,剔除冗余字段,使用短键名
大批量数据优先 JSONLines (jsonl) + 流式解析,避免一次性加载大 JSON
优化结构:降低嵌套,批量传输,时间用时间戳
增量同步,避免全量拉取
极致性能:替换为 MessagePack / Protobuf 二进制格式
本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢