首页 > 解决方案 > 如何以适当的大小压缩 JSON 文件?

问题描述

我正在通过获取 JSON 数据并使用它来绘制边界来制作网页,但由于文件大小约为 22 MB,因此加载需要很长时间。实际上它是一个印度地图 JSON 文件。我有两个文件来绘制 JSON 数据,但一个不包含国家/地区的更新边界,另一个太大。

您是否建议一些资源来压缩它或建议一些其他适当大小的文件?

标签: json

解决方案


序列化

如果结果的大小不必那么小,您可以考虑不同的序列化方法。由于 JSON 是人类可读的语言,它也不是最节省空间的格式。

例如,表示数字 1234.567890123457 在 UTF-8 字符串化 JSON 中将占用 18 个字节。但是,二进制格式可以表示与 8 字节浮点双精度相同的数字。同样 false 将是 JSON 中的 5 个字节,但在二进制格式中是一个字节(或可能更少)。根据数据的结构,使用二进制序列化技术可能会更好。

您可以尝试的一些序列化器是

  • CBOR
  • 微笑
  • BSON
  • 消息包
  • 离子(文本和二进制格式)

这需要进一步测试,但您应该能够使用某些方法轻松地将大小减小一半

压缩

如果你无论如何都想压缩它,请考虑到大多数时候压缩序列化数据会否定使用二进制格式数据序列化的任何优势,最终压缩大小与序列化方法关系不大,几乎所有用压缩方法做。选择最佳压缩算法是在存储数据的成本和压缩数据的成本之间的平衡游戏,但您可以根据预期的生命周期和读取模式选择合适的平衡点。

就我个人而言,我使用 gzip 是因为它速度快、效果好,并且可以在 JVM 中本地工作。但是,您可以选择 Brotli,我听说它在压缩静态前端 javascript 资产方面提供了很好的效果。您还可以尝试 XZ、Zstandard 和 bzip2。

作为压缩的结果,您可以将数据大小减少十倍,但是每次客户端加载页面时下载 2MB 可能仍然太高

压缩示例

例如,在您提供的数据上使用 brotli,我设法将数据大小减少到 3.4MB。我确信压缩方法和序列化的某些不同组合可能会导致数据文件更小,但话又说回来,它可能会对压缩/解压缩速度产生负面影响。使用下面提供的代码在 nodejs 中使用压缩:

const brotli = require('brotli');
const fs = require("fs");
const path = require("path");

const compressed = brotli.compress(fs.readFileSync(path.join(__dirname, "india.json")), {
    mode: 0, // 0 = generic, 1 = text, 2 = font (WOFF2)
    quality: 11, // 0 - 11
    lgwin: 22 // window size
});

我花了大约 2 分钟来完全压缩,但是因为它可以被预压缩,所以它应该没那么重要,但真正重要的是客户端的解压缩速度,在压缩发生的相同环境中需要不到一秒钟.

const data = brotli.decompress(fs.readFileSync("compressed.bin"));
fs.writeFileSync(__dirname + "/decoded.json", data);

推荐阅读