JSON 速度较慢。这里有 4 个更快的替代方案
修改 2:底部有很多很有见地的评论,在选择其他方案之前,也请先阅读一下!
修改 1:从评论中新增了关于“优化 JSON 性能”的见解
您的用户希望即时访问信息、获得快速交互和无缝体验。JSON(JavaScript 对象表示法的缩写)一直是 Web 开发中数据交换的忠实伙伴,但它是否会降低您的应用程序速度?让我们深入探索 JSON 的世界,探索其潜在的瓶颈,并发现更快的替代方案和优化技术,让您的应用程序像猎豹一样快速奔跑。
您可能还想查看本教程:使用 Golang 构建实时通知系统 - 分步通知系统设计指南
什么是 JSON?为何需要关注?
在我们开始 JSON 优化之旅之前,让我们先了解一下什么是 JSON 以及它为什么重要。
JSON 是应用程序中数据粘合的粘合剂。它是服务器和客户端之间进行数据通信的语言,也是数据库和配置文件中数据存储的格式。本质上,JSON 在现代 Web 开发中扮演着关键角色。
理解 JSON 及其细微差别不仅是任何 Web 开发者的一项基本技能,而且对于优化应用程序也至关重要。随着我们深入研究这篇博客,您将发现 JSON 在性能方面为何是一把双刃剑,以及这些知识如何对您的开发之旅产生重大影响。
JSON 的流行以及人们使用它的原因
JSON 在 Web 开发领域的受欢迎程度不容小觑。它之所以成为数据交换的事实标准,有以下几个令人信服的原因:
- 人性化易读格式:JSON 采用直观的文本结构,方便开发人员和非开发人员阅读和理解。这种人性化易读的格式增强了协作能力,并简化了调试。
// Inefficient
{
"customer_name_with_spaces": "John Doe"
}
// Efficient
{
"customerName": "John Doe"
}
-
与语言无关:JSON 不依赖于任何特定的编程语言。它是一种通用数据格式,几乎所有现代编程语言都可以解析和生成,因此具有高度的通用性。
-
数据结构一致性:JSON 使用键值对、数组和嵌套对象来强制数据采用一致的结构。这种一致性使其在各种编程场景中都具有可预测性且易于使用。
// Inefficient
{
"order": {
"items": {
"item1": "Product A",
"item2": "Product B"
}
}
}
// Efficient
{
"orderItems": ["Product A", "Product B"]
}
-
浏览器支持:Web 浏览器原生支持 JSON,允许 Web 应用程序与服务器无缝通信。这种原生支持极大地促进了 JSON 在 Web 开发中的普及。
-
JSON API:许多 Web 服务和 API 默认提供 JSON 格式的数据。这进一步巩固了 JSON 作为 Web 开发中数据交换首选的地位。
-
JSON Schema:开发人员可以使用 JSON Schema 来定义和验证 JSON 数据的结构,为他们的应用程序增加额外的清晰度和可靠性。
鉴于这些优势,全球各地的开发人员都依赖 JSON 来满足数据交换需求也就不足为奇了。然而,随着我们深入探讨本博客,我们将揭示 JSON 可能面临的性能挑战以及如何有效地应对这些挑战。
对速度的需求
用户期望即时访问信息、快速交互以及在 Web 和移动应用之间实现无缝体验。这种对速度的需求源于以下几个因素:
用户期望
用户已经习惯了数字交互中闪电般的响应速度。他们不想等待网页加载或应用程序响应。即使是几秒钟的延迟也会导致沮丧和放弃。
竞争优势
速度是重要的竞争优势。相比反应迟缓的应用程序,响应速度快的应用程序更能吸引和留住用户。
搜索引擎排名
像谷歌这样的搜索引擎会将页面速度作为排名因素。加载速度更快的网站往往在搜索结果中排名更高,从而带来更高的曝光度和流量。
转化率
电子商务网站尤其深知速度对转化率的影响。网站速度越快,转化率就越高,最终收入也就越高。
移动性能
随着移动设备的普及,对速度的需求也愈发迫切。移动用户的带宽和处理能力通常有限,因此快速的应用性能至关重要。
JSON 会减慢我们的应用程序速度吗?
现在,让我们讨论一下核心问题:JSON 是否会减慢我们的应用程序速度?
如前所述,JSON 是一种非常流行的数据交换格式。它灵活、易用且受到广泛支持。然而,这种广泛的采用并不意味着它不会面临性能挑战。
在某些情况下,JSON 可能会成为降低应用程序速度的罪魁祸首。解析 JSON 数据的过程(尤其是在处理大型或复杂结构时)可能会耗费宝贵的几毫秒时间。此外,低效的序列化和反序列化可能会影响应用程序的整体性能。
解析开销
当 JSON 数据到达你的应用程序时,它必须经过解析过程才能转换为可用的数据结构。解析过程可能相对较慢,尤其是在处理大量或深度嵌套的 JSON 数据时。
// JavaScript example using JSON.parse for parsing
const jsonData = '{"key": "value"}';
const parsedData = JSON.parse(jsonData);
序列化和反序列化
JSON 要求数据在从客户端发送到服务器时进行序列化(将对象编码为字符串),并在接收时进行反序列化(将字符串转换回可用的对象)。这些步骤可能会增加开销并影响应用程序的整体速度。
// Node.js example using JSON.stringify for serialization
const data = { key: 'value' };
const jsonString = JSON.stringify(data);
字符串操作
JSON 是基于文本的,严重依赖于字符串操作,例如连接和解析等操作。与处理二进制数据相比,字符串处理速度可能较慢。
缺乏数据类型
JSON 的数据类型有限(例如字符串、数字、布尔值)。复杂的数据结构可能需要效率较低的表示,从而导致内存占用增加、处理速度变慢。
{
"quantity": 1.0
}
冗长
JSON 的可读性设计可能会导致数据过于冗长。冗余的键和重复的结构会增加负载大小,从而延长数据传输时间。
// Inefficient
{
"product1": {
"name": "Product A",
"price": 10
},
"product2": {
"name": "Product A",
"price": 10
}
}
无二进制支持
JSON 缺乏对二进制数据的原生支持。处理二进制数据时,开发人员通常需要将其编码并解码为文本,效率较低。
深层嵌套
在某些情况下,JSON 数据可能嵌套很深,需要递归解析和遍历。这种计算复杂性会降低应用程序的速度,尤其是在没有优化的情况下。
与此类似,我和其他热爱开源的开发者在 Slack 上运营一个以开发者为中心的社区。我们在这里讨论各种主题,包括实现、集成、一些爆料、奇葩聊天、线上聚会,为开源做贡献,以及一切有助于开发者保持理智的事情 ;) 毕竟,知识过量也可能带来危险。
我诚邀您加入我们的免费社区(我保证没有广告,而且我打算一直保持这种状态),参与讨论,分享您的精彩经验和专业知识。您可以填写这张表格,几天后您的 Slack 邀请函就会发送到您的邮箱。我们拥有来自一些优秀公司(Atlassian、Gong、Scaler)的优秀员工,您一定不想错过与他们互动的机会。邀请表格
我们继续吧...
JSON 的替代方案
虽然 JSON 是一种用途广泛的数据交换格式,但其在某些情况下的性能限制促使人们探索更快的替代方案。让我们深入研究其中一些替代方案,并了解何时以及为何选择它们:
协议缓冲区
协议缓冲区(Protocol Buffers,也称为 protobuf)是 Google 开发的一种二进制序列化格式。它在速度和效率方面非常出色。以下是您可以考虑使用协议缓冲区的原因:
-
二进制编码:协议缓冲区使用二进制编码,与 JSON 的基于文本的编码相比,它更紧凑,编码和解码速度更快。
-
高效的数据结构:协议缓冲区允许您定义具有精确类型的高效数据结构,从而实现更快的序列化和反序列化。
-
模式演变:协议缓冲区支持模式演变,这意味着您可以更新数据结构而不会破坏向后兼容性。
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
}
消息包
MessagePack 是另一种专为提高效率和速度而设计的二进制序列化格式。以下是您可以考虑使用 MessagePack 的原因:
-
紧凑性:MessagePack 生成高度紧凑的数据表示,从而减少数据传输大小。
-
二进制数据:MessagePack 为二进制数据提供原生支持,使其成为涉及二进制信息的场景的理想选择。
-
速度:MessagePack 的二进制特性允许快速编码和解码。
// JavaScript example using MessagePack for serialization
const msgpack = require('msgpack-lite');
const data = { key: 'value' };
const packedData = msgpack.encode(data);
BSON(二进制 JSON)
BSON,通常发音为“bee-son”或“bi-son”,是一种主要用于 MongoDB 等数据库的二进制序列化格式。以下是您可以考虑使用 BSON 的原因:
-
类似 JSON 的结构:BSON 维护类似 JSON 的结构并添加二进制数据类型,在效率和可读性之间取得平衡。
-
二进制数据支持:BSON 为二进制数据类型提供本机支持,这有利于处理图像或多媒体等数据。
-
数据库集成:BSON 与 MongoDB 等数据库无缝集成,使其成为此类环境的自然选择。
{
"_id": ObjectId("60c06fe9479e1a1280e6bfa7"),
"name": "John Doe",
"age": 30
}
阿芙罗
Avro 是 Apache Hadoop 项目内部开发的数据序列化框架。它注重模式兼容性和性能。以下是您可以考虑使用 Avro 的原因:
-
模式兼容性:Avro 优先考虑模式兼容性,允许您在不破坏兼容性的情况下改进数据结构。
-
二进制数据:Avro 使用紧凑的二进制编码格式进行数据传输,从而产生更小的有效载荷。
-
语言中立:Avro 支持多种编程语言,使其适用于多样化的应用生态系统。
{
"type": "record",
"name": "Person",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "age", "type": "int" }
]
}
JSON 及其替代方案的选择取决于您的具体用例和需求。如果模式兼容性至关重要,Avro 可能是您的最佳选择。如果您追求紧凑性和效率,MessagePack 和 Protocol Buffers 是强有力的竞争者。处理二进制数据时,MessagePack 和 BSON 可以满足您的需求。每种格式都有其优缺点,因此请选择符合您项目需求的格式。
优化 JSON 性能
但是,如果您不顾 JSON 可能存在的运行障碍,坚持使用它,该怎么办呢?如何让 JSON 运行得更快、更高效?好消息是,有一些实用的策略和优化方法可以帮助您实现这一目标。让我们通过代码示例和最佳实践来探索这些策略。
1.最小化数据大小
a.使用简短、描述性的键:选择简洁但有意义的键名以减少 JSON 对象的大小。
// Inefficient
{
"customer_name_with_spaces": "John Doe"
}
// Efficient
{
"customerName": "John Doe"
}
b.尽可能缩写:在不影响清晰度的情况下,考虑使用键或值的缩写。
// Inefficient
{
"transaction_type": "purchase"
}
// Efficient
{
"txnType": "purchase"
}
2. 合理使用数组
a.最小化嵌套:避免深度嵌套数组,因为它们会增加解析和遍历 JSON 的复杂性。
// Inefficient
{
"order": {
"items": {
"item1": "Product A",
"item2": "Product B"
}
}
}
// Efficient
{
"orderItems": ["Product A", "Product B"]
}
3. 优化数字表示
a.尽可能使用整数:如果一个值可以表示为整数,则使用它而不是浮点数。
// Inefficient
{
"quantity": 1.0
}
// Efficient
{
"quantity": 1
}
4. 消除冗余
a.避免重复数据:通过引用共享值消除冗余数据。
// Inefficient
{
"product1": {
"name": "Product A",
"price": 10
},
"product2": {
"name": "Product A",
"price": 10
}
}
// Efficient
{
"products": [
{
"name": "Product A",
"price": 10
},
{
"name": "Product B",
"price": 15
}
]
}
5.使用压缩
a.应用压缩算法:如果适用,请使用 Gzip 或 Brotli 等压缩算法来减少传输过程中 JSON 有效负载的大小。
// Node.js example using zlib for Gzip compression
const zlib = require('zlib');
const jsonData = {
// Your JSON data here
};
zlib.gzip(JSON.stringify(jsonData), (err, compressedData) => {
if (!err) {
// Send compressedData over the network
}
});
根据 Samuel 的评论,我添加了一条编辑。
As Samuel rightly observes, the adoption of HTTP/2 has brought significant advancements, particularly in optimizing data interchange formats like JSON. HTTP/2's multiplexing capabilities efficiently manage multiple requests over a single connection, enhancing responsiveness and reducing overhead.
In practical terms, a comprehensive optimization strategy may involve both embracing HTTP/2 and utilizing compression techniques per your use-case, recognizing that each approach addresses specific aspects of network efficiency and performance. HTTP/2 excels in network-level optimization, while compression strategies enhance application-level efficiency, and the synergy between them can lead to substantial gains in data handling speed and resource utilization.
6. 使用服务器端缓存
a.缓存 JSON 响应:实现服务器端缓存,以有效地存储和提供 JSON 响应,减少重复数据处理的需要。
7. 分析和优化
a.分析性能:使用分析工具来识别 JSON 处理代码中的瓶颈,然后优化这些部分。
请记住,您实施的具体优化应符合应用程序的要求和限制。
现实世界的优化:实践中加速 JSON
既然您已经探索了 JSON 优化的理论层面,现在是时候深入研究那些在使用 JSON 时遇到性能瓶颈并成功克服这些瓶颈的实际应用程序和项目了。这些示例提供了宝贵的见解,让我们了解如何在充分利用 JSON 的多功能性的同时,提高速度和响应能力。
1. LinkedIn 的 Protocol Buffers 集成
挑战:LinkedIn 与 JSON 冗长性和网络带宽占用的斗争
全球最大的职业社交平台 LinkedIn 面临着一项艰巨的挑战。他们依赖 JSON 进行微服务通信,导致代码冗长,增加了网络带宽占用,最终导致延迟增加。在分秒必争的数字世界中,这是一个亟待解决的挑战。
解决方案:协议缓冲区的强大功能
LinkedIn 采用了协议缓冲区(Protocol Buffers,通常简称为 protobuf),这是 Google 开发的一种二进制序列化格式。协议缓冲区的主要优势在于其效率、紧凑性和速度,使其序列化和反序列化速度明显快于 JSON。
影响:减少延迟高达 60%
采用 Protocol Buffers 显著降低了延迟,报告显示延迟提升高达 60%。这项优化显著提升了 LinkedIn 服务的速度和响应能力,为全球数百万用户带来了更流畅的体验。
2. Uber 的 H3 地理索引
挑战:Uber 地理空间数据的 JSON 难题
网约车巨头 Uber 的运营严重依赖地理空间数据。JSON 曾是地理空间数据的默认表示方式,但事实证明,解析大型数据集的 JSON 是一个瓶颈,会降低其算法的速度。
解决方案:引入 H3 地理索引
Uber 推出了H3 Geo-Index,这是一种用于地理空间数据的高效六边形网格系统。通过从 JSON 迁移到这一创新解决方案,他们成功显著降低了 JSON 解析开销。
影响:加速地理空间运营
此次优化显著加速了地理空间操作,提升了Uber叫车服务和地图系统的效率。用户体验到了更快的响应时间和更可靠的服务。
3. Slack 的消息格式优化
挑战:Slack 与实时消息渲染的斗争
Slack 是一个团队消息平台,需要在实时聊天中传输和渲染大量 JSON 格式的消息。然而,这导致了性能瓶颈和消息渲染缓慢。
解决方案:精简 JSON 结构
Slack 优化了 JSON 结构,以减少不必要的数据。他们开始在每条消息中只包含必要的信息,从而缩减了负载大小。
影响:更快的消息呈现和增强的聊天性能
此次优化显著提升了消息渲染速度。Slack 用户享受到了更灵敏、更高效的聊天体验,尤其是在繁忙的群聊中。
4. Auth0 的 Protocol Buffers 实现
挑战:Auth0 的身份验证和授权数据性能
Auth0 是一个著名的身份和访问管理平台,它在处理身份验证和授权数据时面临着 JSON 的性能挑战。这些数据需要在不影响安全性的情况下高效处理。
解决方案:采用协议缓冲区进行数据序列化
Auth0也转向了协议缓冲区 (Protocol Buffers) ,利用其高效的数据序列化和反序列化功能。这一转变显著提高了数据处理速度,使身份验证过程更快,并提升了整体性能。
影响:增强身份验证和授权
协议缓冲区的采用增强了身份验证和授权流程,确保 Auth0 的服务提供一流的性能,同时保持最高的安全标准。
这些真实案例凸显了优化在克服 JSON 相关速度下降方面所发挥的强大作用。这些案例中所采用的策略证明了 JSON 及其他格式在满足现代数字环境需求方面的适应性和多功能性。
请继续关注结论部分,我们将在其中总结关键要点并为您提供在自己的项目中优化 JSON 性能的路线图。
结束语
JSON 是功能多样且不可或缺的数据交换工具。其易于理解的结构和跨语言的适应性使其成为当代应用程序的基石。然而,正如我们在本指南中所探讨的那样,JSON 的广泛使用并不意味着它能够免受性能挑战。
我们在增强 JSON 性能的过程中获得的关键结论显而易见:
-
- 性能至上:在当今的数字时代,速度和响应能力至关重要。用户要求应用程序能够以闪电般的速度运行,即使是轻微的延迟也可能导致用户不满并错失良机。
-
- 大小至关重要:数据负载的大小直接影响网络带宽使用率和响应时间。减小数据大小通常是优化 JSON 性能的第一步。
-
- 探索替代格式:当效率和速度至关重要时,探索替代数据序列化格式(如协议缓冲区、MessagePack、BSON 或 Avro)是有益的。
-
- 现实世界的例子:从现实世界的案例中学习,组织有效地解决了与 JSON 相关的减速问题,表明优化工作可以显著提高应用程序性能。
文章来源:https://dev.to/nikl/json-is-slower-here-are-its-4-faster-alternatives-2g30与此类似,我和其他热爱开源的开发者在 Slack 上运营一个以开发者为中心的社区。我们在这里讨论各种主题,包括实现、集成、一些爆料、奇葩聊天、线上聚会,为开源做贡献,以及一切有助于开发者保持理智的事情 ;) 毕竟,知识过量也可能带来危险。
我诚邀您加入我们的免费社区(我保证没有广告,而且我打算一直保持这种状态),参与讨论,分享您的精彩经验和专业知识。您可以填写这张表格,几天后您的 Slack 邀请函就会发送到您的邮箱。我们拥有来自一些优秀公司(Atlassian、Gong、Scaler)的优秀员工,您一定不想错过与他们互动的机会。邀请表格
如果您能与贡献者的开发者朋友分享该表格,我将不胜感激。
这是一个有趣的笔记和选项集合。感谢这篇文章!
您能提供一些链接吗,尤其是“实际优化”部分的链接?我很想了解更多关于这些不同公司和不同情况的经验。
在“优化 JSON 性能”部分中,示例建议在 JavaScript 中使用压缩来提升性能。通常应避免使用压缩,而应在连接级别使用 HTTP 压缩。HTTP 支持相同的 zlib、gzip 和 brotli 压缩选项,但实现效率可能更高。
虽然协议缓冲区和其他二进制选项无疑提供了 JSON 所不具备的性能和功能,但我认为它低估了 HTTP 压缩和 HTTP/2 的重要性。
十年前,我在电商行业工作时,做过一些小型的 JSON 结构优化工作,旨在降低传输大小和遍历成本。虽然使用列式数据(数组对象)相对于通常的“集合”(对象数组)仍然有一些优势,但如果重复使用,一些已发现的问题(例如冗长的键)基本上可以通过压缩来消除。
HTTP/2 还降低了请求的开销成本,使得以更小的片段请求 JSON(或任何格式)并将它们累积在客户端以提高响应能力变得更加高效。
虽然存在一些小的格式问题,并且缺乏资料,但它提供了大量信息和建议。