JSON非常慢:这里有更快的替代方案!

开发 前端
在不断变化的网络开发环境中,优化 JSON 性能是一项宝贵的技能,它能让你的项目与众不同,并确保你的应用程序在即时数字体验时代茁壮成长。

是的,你没听错!JSON,这种在网络开发中普遍用于数据交换的格式,可能正在拖慢我们的应用程序。在速度和响应性至关重要的世界里,检查 JSON 的性能影响至关重要。在这篇博客中,深入探讨 JSON 可能成为应用程序瓶颈的原因,并探索更快的替代方法和优化技术,使您的应用程序保持最佳运行状态。

JSON 是什么,为什么要关心?

图片图片

JSON 是 JavaScript Object Notation 的缩写,一种轻量级数据交换格式,已成为应用程序中传输和存储数据的首选。它的简单性和可读格式使开发者和机器都能轻松使用。但是,为什么要在项目中关注 JSON 呢?

JSON 是应用程序中数据的粘合剂。它是服务器和客户端之间进行数据通信的语言,也是数据库和配置文件中存储数据的格式。从本质上讲,JSON 在现代网络开发中起着举足轻重的作用。

JSON 的流行以及人们使用它的原因...

主要有就下几点:

  1. 人类可读格式:JSON 采用简单明了、基于文本的结构,便于开发人员和非开发人员阅读和理解。这种人类可读格式增强了协作,简化了调试。
  2. 语言无关:JSON 与任何特定编程语言无关。它是一种通用的数据格式,几乎所有现代编程语言都能对其进行解析和生成,因此具有很强的通用性。
  3. 数据结构一致性:JSON 使用键值对、数组和嵌套对象来实现数据结构的一致性。这种一致性使其具有可预测性,便于在各种编程场景中使用。
  4. 浏览器支持:浏览器原生支持 JSON,允许应用程序与服务器进行无缝通信。这种本地支持极大地促进了 JSON 在开发中的应用。
  5. JSON API:许多服务和应用程序接口默认以 JSON 格式提供数据。这进一步巩固了 JSON 在网络开发中作为数据交换首选的地位。
  6. JSON 模式:开发人员可以使用 JSON 模式定义和验证 JSON 数据的结构,从而为其应用程序增加一层额外的清晰度和可靠性。

鉴于这些优势,难怪全球的开发人员都依赖 JSON 来满足他们的数据交换需求。不过,随着我们深入探讨,会发现与 JSON 相关的潜在性能问题以及如何有效解决这些挑战。

对速度的需求

应用速度和响应速度的重要性

在当今快节奏的数字环境中,应用程序的速度和响应能力是不容忽视的。用户希望在网络和移动应用中即时获取信息、快速交互和无缝体验。对速度的这种要求是由多种因素驱动的:

  1. 用户期望:用户已习惯于从数字互动中获得闪电般快速的响应。他们不想等待网页加载或应用程序响应。哪怕是几秒钟的延迟,都会导致用户产生挫败感并放弃使用。
  2. 竞争优势:速度可以成为重要的竞争优势。与反应慢的应用程序相比,反应迅速的应用程序往往能更有效地吸引和留住用户。
  3. 搜索引擎排名:谷歌等搜索引擎将页面速度视为排名因素。加载速度更快的网站往往在搜索结果中排名靠前,从而提高知名度和流量。
  4. 转换率:电子商务网站尤其清楚速度对转换率的影响。网站速度越快,转换率越高,收入也就越高。
  5. 移动性能:随着移动设备的普及,对速度的需求变得更加重要。移动用户的带宽和处理能力往往有限,因此,快速的应用程序性能必不可少。

JSON 会拖慢我们的应用程序吗?

在某些情况下,JSON 可能是导致应用程序运行速度减慢的罪魁祸首。解析 JSON 数据的过程,尤其是在处理大型或复杂结构时,可能会耗费宝贵的毫秒时间。此外,低效的序列化和反序列化也会影响应用程序的整体性能。

JSON 为什么会变慢

1.解析开销

JSON 数据到达应用程序后,必须经过解析过程才能转换成可用的数据结构。解析过程可能相对较慢,尤其是在处理大量或深度嵌套的 JSON 数据时。

2.序列化和反序列化

JSON 要求在从客户端向服务器发送数据时进行序列化(将对象编码为字符串),并在接收数据时进行反序列化(将字符串转换回可用对象)。这些步骤会带来开销并影响应用程序的整体速度。

在微服务架构的世界里,JSON 通常用于在服务之间传递消息。但是,JSON 消息需要序列化和反序列化,这两个过程会带来巨大的开销。

在众多微服务不断通信的情况下,这种开销可能会累积起来,有可能会使应用程序减慢到影响用户体验的程度。

图片图片

3.字符串操作

JSON 以文本为基础,主要依靠字符串操作来进行连接和解析等操作。与处理二进制数据相比,字符串处理速度较慢。

4.缺乏数据类型

JSON 的数据类型(如字符串、数字、布尔值)有限。复杂的数据结构可能需要效率较低的表示方法,从而导致内存使用量增加和处理速度减慢。

图片图片

5.冗长性

JSON 的人机可读设计可能导致冗长。冗余键和重复结构会增加有效载荷的大小,导致数据传输时间延长。

6.不支持二进制

JSON 缺乏对二进制数据的本地支持。在处理二进制数据时,开发人员通常需要将其编码和解码为文本,这可能会降低效率。

7.深嵌套

在某些情况下,JSON 数据可能嵌套很深,需要进行递归解析和遍历。这种计算复杂性会降低应用程序的运行速度,尤其是在没有优化的情况下。

JSON 的替代品

虽然 JSON 是一种通用的数据交换格式,但由于其在某些情况下的性能限制,开发者开始探索更快的替代格式。我们来看呓2其中的一些替代方案。

1.协议缓冲区(protobuf)

协议缓冲区(通常称为 protobuf)是谷歌开发的一种二进制序列化格式。其设计宗旨是高效、紧凑和快速。Protobuf 的二进制特性使其在序列化和反序列化时比 JSON 快得多。

何时使用:当你需要高性能数据交换时,尤其是在微服务架构、物联网应用或网络带宽有限的情况下,请考虑使用 protobuf。

2. MessagePack 信息包

MessagePack 是另一种二进制序列化格式,以速度快、结构紧凑而著称。其设计目的是在保持与各种编程语言兼容的同时,提高比 JSON 更高的效率。

何时使用:当你需要在速度和跨语言兼容性之间取得平衡时,MessagePack 是一个不错的选择。它适用于实时应用程序和对减少数据量有重要要求的情况。

3. BSON(二进制 JSON)

BSON 或二进制 JSON 是一种从 JSON 衍生出来的二进制编码格式。它保留了 JSON 的灵活性,同时通过二进制编码提高了性能。BSON 常用于 MongoDB 等数据库。

何时使用:如果你正在使用 MongoDB,或者需要一种能在 JSON 和二进制效率之间架起桥梁的格式,那么 BSON 就是一个很有价值的选择。

4. Apache Avro(阿帕奇 Avro)

Apache Avro 是一个数据序列化框架,专注于提供一种紧凑的二进制格式。它基于模式,可实现高效的数据编码和解码。

何时使用:Avro 适用于模式演进非常重要的情况,如数据存储,以及需要在速度和数据结构灵活性之间取得平衡的情况。

与 JSON 相比,这些替代方案在性能上有不同程度的提升,具体选择取决于您的具体使用情况。通过考虑这些替代方案,您可以优化应用程序的数据交换流程,确保将速度和效率放在开发工作的首位。


每个字节的重要性:优化数据格式

JSON 数据

下面是我们的 JSON 数据示例片段:

{
  "id": 1,                                 // 14 bytes
  "name": "John Doe",                      // 20 bytes
  "email": "johndoe@example.com",          // 31 bytes
  "age": 30,                               // 9 bytes
  "isSubscribed": true,                    // 13 bytes
  "orders": [                              // 11 bytes
    {                                      // 2 bytes
      "orderId": "A123",                   // 18 bytes
      "totalAmount": 100.50                // 20 bytes
    },                                     // 1 byte
    {                                      // 2 bytes
      "orderId": "B456",                   // 18 bytes
      "totalAmount": 75.25                 // 19 bytes
    }                                      // 1 byte
  ]                                        // 1 byte
}

JSON 总大小: ~139 字节

JSON 功能多样,易于使用,但也有缺点,那就是它的文本性质。每个字符、每个空格和每个引号都很重要。在数据大小和传输速度至关重要的情况下,这些看似微不足道的字符可能会产生重大影响。

效率挑战:使用二进制格式减少数据大小

现在,我们提供其他格式的数据表示并比较它们的大小:

**协议缓冲区 (protobuf)**:

syntax = "proto3";

message User {
  int32 id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
  bool is_subscribed = 5;
  repeated Order orders = 6;

  message Order {
    string order_id = 1;
    float total_amount = 2;
  }
}
0A 0E 4A 6F 68 6E 20 44 6F 65 0C 4A 6F 68 6E 20 44 6F 65 65 78 61 6D 70 6C 65 2E 63 6F 6D 04 21 00 00 00 05 01 12 41 31 32 33 03 42 DC CC CC 3F 05 30 31 31 32 34 34 35 36 25 02 9A 99 99 3F 0D 31 02 42 34 35 36 25 02 9A 99 99 3F

协议缓冲区总大小: ~38 字节

MessagePack

二进制表示法(十六进制):

a36a6964000000000a4a6f686e20446f650c6a6f686e646f65406578616d706c652e636f6d042100000005011241313302bdcccc3f0530112434353625029a99993f

信息包总大小: ~34 字节

Binary Representation (Hexadecimal):

3e0000001069640031000a4a6f686e20446f6502656d61696c006a6f686e646f65406578616d706c652e636f6d1000000022616765001f04370e4940

BSON 总大小: ~43 字节

Avro

二进制表示法(十六进制):

0e120a4a6f686e20446f650c6a6f686e646f65406578616d706c652e636f6d049a999940040a020b4108312e3525312e323538323539

Avro 总大小: ~32 字节

图片图片

现在,你可能想知道,为什么这些格式中的某些会输出二进制数据,但它们的大小却各不相同。Avro、MessagePack 和 BSON 等二进制格式具有不同的内部结构和编码机制,这可能导致二进制表示法的差异,即使它们最终表示的是相同的数据。下面简要介绍一下这些差异是如何产生的:

1. Avro

  • Avro 使用模式对数据进行编码,这种模式通常包含在二进制表示法中。
  • Avro 基于模式的编码通过提前指定数据结构,实现了高效的数据序列化和反序列化。
  • Avro 的二进制格式设计为自描述格式,这意味着模式信息包含在编码数据中。这种自描述性使 Avro 能够保持不同版本数据模式之间的兼容性。

2. MessagePack

  • MessagePack 是一种二进制序列化格式,直接对数据进行编码,不包含模式信息。
  • 它使用长度可变的整数和长度可变的字符串的紧凑二进制表示法,以尽量减少空间使用。
  • MessagePack 不包含模式信息,因此更适用于模式已提前知晓并在发送方和接收方之间共享的情况。

3. BSON

  • BSON 是 JSON 数据的二进制编码,包括每个值的类型信息。
  • BSON 的设计与 JSON 紧密相连,但它增加了二进制数据类型,如 JSON 缺乏的日期和二进制数据。
  • 与 MessagePack 一样,BSON 不包括模式信息。

这些设计和编码上的差异导致了二进制表示法的不同:

  • Avro 包含模式信息并具有自描述性,因此二进制文件稍大,但与模式兼容。
  • MessagePack 的编码长度可变,因此非常紧凑,但缺乏模式信息,因此适用于已知模式的情况。
  • BSON 与 JSON 关系密切,并包含类型信息,与 MessagePack 等纯二进制格式相比,BSON 的大小会有所增加。

总之,这些差异源于每种格式的设计目标和特点。Avro 优先考虑模式兼容性,MessagePack 侧重于紧凑性,而 BSON 在保持类似 JSON 结构的同时增加了二进制类型。格式的选择取决于您的具体使用情况和要求,如模式兼容性、数据大小和易用性。

优化 JSON 性能

下面是一些优化 JSON 性能的实用技巧以及代码示例和最佳实践:

1.最小化数据大小

  • 使用简短的描述性键名:选择简洁但有意义的键名,以减少 JSON 对象的大小
// Inefficient
{
  "customer_name_with_spaces": "John Doe"
}

// Efficient
{
  "customerName": "John Doe"
}
  • 尽可能缩写:在不影响清晰度的情况下,考虑对键或值使用缩写。
// 效率低
{
  "transaction_type": "purchase"
}
 
// 效率高
{
  "txnType": "purchase"
}

2.明智使用数组

  • 尽量减少嵌套:避免深度嵌套数组,因为它们会增加解析和遍历 JSON 的复杂性。
// 效率低
{
  "order": {
    "items": {
      "item1": "Product A",
      "item2": "Product B"
    }
  }
}

// 效率高
{
  "orderItems": ["Product A", "Product B"]
}

3.优化数字表示法

尽可能使用整数:如果数值可以用整数表示,就用整数代替浮点数。

// 效率低
{
  "quantity": 1.0
}

// 效率高
{
  "quantity": 1
}

4.删除冗余

避免重复数据:通过引用共享值来消除冗余数据。

// 效率低
{
  "product1": {
    "name": "Product A",
    "price": 10
  },
  "product2": {
    "name": "Product A",
    "price": 10
  }
}

// 效率高
{
  "products": [
    {
      "name": "Product A",
      "price": 10
    },
    {
      "name": "Product B",
      "price": 15
    }
  ]
}

5.使用压缩

应用压缩算法:如果适用,在传输过程中使用 Gzipor Brotlito 等压缩算法来减小 JSON 有效负载的大小。

// 使用 zlib 进行 Gzip 压缩的 Node.js 示例
const zlib = require('zlib');

const jsonData = {
  // 在这里填入你的 JSON 数据
};

zlib.gzip(JSON.stringify(jsonData), (err, compressedData) => {
  if (!err) {
    // 通过网络发送 compressedData
  }
});

6.采用服务器端缓存:

缓存 JSON 响应:实施服务器端缓存,高效地存储和提供 JSON 响应,减少重复数据处理的需要。

7.配置文件和优化

剖析性能:使用剖析工具找出 JSON 处理代码中的瓶颈,然后优化这些部分。

实际优化:在实践中加快 JSON 的处理速度

在本节中,我们将探讨实际案例,这些案例在使用 JSON 时遇到性能瓶颈并成功克服。我们会看到诸如 LinkedIn、Auth0、Uber 等知名技术公司如何解决 JSON 的限制并改善他们应用的性能。这些案例为如何提升应用处理速度和响应性提供了实用的策略。

1.LinkedIn 的协议缓冲区集成:

  • 挑战:LinkedIn 面临的挑战是 JSON 的冗长以及由此导致的网络带宽使用量增加,从而导致延迟增加。
  • 解决方案:他们采用了 Protocol Buffers,这是一种二进制序列化格式,用以替换微服务通信中的 JSON。
  • 影响:这一优化将延迟降低了 60%,提高了 LinkedIn 服务的速度和响应能力。

2.Uber 的 H3 地理索引:

挑战:Uber 使用 JSON 来表示各种地理空间数据,但解析大型数据集的 JSON 会降低其算法速度。

解决方案:他们引入了 H3 Geo-Index,这是一种用于地理空间数据的高效六边形网格系统,可减少 JSON 解析开销。

影响:这一优化大大加快了地理空间业务的发展,增强了 Uber 的叫车和地图服务。

3.Slack 的信息格式优化:

挑战:Slack 需要在实时聊天中传输和呈现大量 JSON 格式的消息,这导致了性能瓶颈。

解决方案:他们优化了 JSON 结构,减少了不必要的数据,只在每条信息中包含必要的信息。

影响:这项优化使得消息展现更快,从而提高了 Slack 用户的整体聊天性能。

4.Auth0 的协议缓冲区实现:

挑战:Auth0 是一个流行的身份和访问管理平台,在处理身份验证和授权数据时面临着 JSON 的性能挑战。

解决方案:他们采用协议缓冲区(Protocol Buffers)来取代 JSON,以编码和解码与身份验证相关的数据。

影响:这一优化大大提高了数据序列化和反序列化的速度,从而加快了身份验证流程,并增强了 Auth0 服务的整体性能。

这些现实世界中的例子展示了通过优化策略解决 JSON 的性能挑战如何对应用程序的速度、响应速度和用户体验产生实质性的积极影响。它们强调了考虑替代数据格式和高效数据结构的重要性,以克服各种情况下与 JSON 相关的速度减慢问题。

结论

在不断变化的网络开发环境中,优化 JSON 性能是一项宝贵的技能,它能让你的项目与众不同,并确保你的应用程序在即时数字体验时代茁壮成长。

责任编辑:武晓燕 来源: 大迁世界
相关推荐

2024-01-10 08:36:10

延时关闭订单

2020-03-09 14:42:40

人工智能机器学习技术

2018-03-25 09:11:31

大数据机器学习分析软件

2019-09-17 17:21:42

数据库ElasticSear跳槽那些事儿

2023-10-19 11:58:56

2020-06-12 07:36:33

Redis

2015-09-20 15:50:46

2018-04-02 11:22:31

大数据Hadoop数据处理

2016-08-23 00:39:25

2019-09-22 18:53:27

Jupyter Not代码开发

2020-03-17 10:35:40

大数据IT人工智能

2019-11-08 09:46:34

技术功能开发

2020-11-30 10:58:52

Linux操作系统Windows

2020-11-02 15:49:35

机器学习技术云计算

2021-10-13 17:58:57

模型人工智能函数

2015-08-04 10:34:13

Windows 10升级

2018-07-30 09:33:21

2020-05-22 13:32:24

可视化词云图数据

2018-07-12 14:57:07

移动办公

2017-08-03 11:56:37

点赞
收藏

51CTO技术栈公众号