在浏览器中,二进制格式比JSON更优秀

  每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行! 订阅:https://rengongzhineng.io/

一位开发者在其近期的性能基准测试回顾中指出,早前在对比 JSON.parsebinaryEncoding.parse 的过程中存在关键错误。他原本直接对比从字符串中解析JSON数据与从缓冲区中解析二进制数据的性能,然而这种对比方式忽略了多个影响因素,因此无法反映真实差距。

首先,缓冲区解码为字符串本身就非常昂贵。相比之下,JSON在此流程中直接跳过了该步骤,但事实上,无论如何,浏览器在接收字节数据时必须在某个阶段完成解码。

其次,JSON格式的消息比二进制格式要大得多。这意味着浏览器中涉及该消息的其他处理流程(例如网络传输代码)也将耗费更多资源,尤其是内存拷贝等操作。仅仅比较反序列化时间,并不能全面反映JSON带来的性能成本。

作者通过图表展示了在不同编码方案下的未压缩消息体积以及从服务器读取消息体的耗时情况,指出JSON在解码开始前就已处于巨大劣势。其原因不仅在于消息体本身更大,还在于需要先将其解码为字符串,之后才能反序列化。

为纠正这一偏差,作者采用了端到端的延迟衡量方式:从发送请求到客户端处理完成的整个过程,并从中扣除纯服务器端耗时,以提取出客户端的真实耗时数据。

关于压缩

虽然压缩确实在网络传输上基本消除了各类编码方案之间的大小差异,但浏览器在接收到压缩数据后仍需解压并处理完整字节流。因此,作者强调其测量方式可以更全面地捕捉这一额外的开销。

Schema与Schema-less编码

部分编码格式如Protobuf具备Schema机制,能在反序列化阶段自动进行数据验证。而JSON等无Schema格式则需手动实现这一功能。虽然在测试中,是否具备Schema对性能影响不大,但这类编码格式能“免费”提供更高的数据安全性,依旧值得强调。

惰性解码与类型支持差异

作者指出,Flatbuffers与Cap’n Proto等库采用了惰性解码策略,只有在真正访问属性时才会进行解码。与其将Flatbuffers的“deserialize”方法直接对比JSON.parse并不公平,因为后者会立即分配并构建实际的值。

另外,不同编码方案对数据类型的支持差异也影响了测试结果。例如,Bebop原生支持Date类型,而JSON则需先转为字符串或数字再手动还原。在本次测试中,作者特别设计了统一的输出对象——“Plain Old JavaScript Object”,其中强制将日期类型和惰性字段完全物化,以确保各编码方案在同等条件下对比。

浏览器端性能改进趋势

虽然支持快速二进制编码的浏览器API早在2020年前就已存在,但直到最近两年才得到更广泛应用。多个编码库也在此期间获得了重大性能提升:

Bebop

Bebop于2020年推出,与Protobuf类似,具备良好工具支持与性能表现,且原生支持Date类型,专为浏览器高性能场景而设计。然而,其社区影响力较小,官方网站目前已跳转至“text-os.com”,令人对其未来发展感到担忧。

Avro(通过avsc库)

截至2025年4月,avsc库在浏览器端仍使用性能极差的Buffer polyfill,导致反序列化极慢。但作者指出,其主分支最新版本已改用原生Uint8Array,显著提升了性能,使其成为本次测试中最具性能优势的选项之一。

Protobuf(protobuf.js)

默认配置下,protobuf.js在反序列化方面表现不佳,问题在于其字符串解码算法效率不高。作者对其源码进行了修改并提交了pull request。同时他也测试了其他Protobuf实现,如protobuf-es(性能差)与pbf(性能佳但缺乏灵活性)。

其他库测试

  • Flatbuffers:工具链完善,惰性加载适用于部分场景。但若需构建完整JS对象,性能不及其他方案。
  • Cap’n Proto:官方JS实现仅适配Node.js,基于C++模块封装,不支持现代浏览器,且文档中也注明性能较差。capnp-es版本虽支持浏览器,但性能仍不理想,最终从测试中剔除。
  • MessagePack与CBOR:msgpackr与cbor-x在服务器端表现良好,但在浏览器端却是测试中最慢的选项之一。

JSON的非性能问题

作者指出,即便不谈性能,JSON本身也存在诸多缺陷:

  • 必须使用字符串输入:限制大数据量处理,Node.js与Chrome均对字符串长度有硬性上限。
  • 类型支持受限、无Schema:例如64位整数在JSON中无法安全表示,常使用字符串规避,极易引发数据错误。
  • 无自动验证机制:缺乏schema机制,需手动验证数据结构与类型。

他分享了一段亲身经历:某次项目中,为避免BigInt精度问题,团队以字符串保存数字,他错误地将数字500与字符串"500"相加,最终导致广告系统向客户请求了第500,500条广告,而非预期的第1000条,造成了实际损失。

作者补充道,如今多数开发者已使用TypeScript以避免此类问题,但JSON并未提供任何结构性保护,反而加大了错误风险。开发者仍需借助zod等额外库实现验证。

服务端性能表现

在Rust服务器上的测试表明,JSON的序列化速度也落后于其他格式。

总结与未来计划

综上,作者认为Bebop、Avro和Protobuf在将服务器端消息发送至浏览器的场景下,都能在性能上优于JSON。目前Avro仍待新版本正式发布,而Protobuf也有待其PR被接受。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值