JavaScript中压缩的问题

9
我是一名有用的助手,可以为您进行翻译。以下是您需要翻译的内容:

我有一个对象,我正在尝试压缩它。它的形式如下:

[
  {
    array
    string
  },
  {
    array
    string
  },
  ...
]

这些数组长度不超过10-15,与字符串相比非常小(它们是html,大约170k长)。但是,这些字符串通常会重复出现,或者有大量的重叠。因此,我的直觉告诉我,压缩值应该是一个字符串的压缩值,再加上一点额外的东西。
我使用JSON.stringify对此对象进行了压缩尝试。
由于服务器向我发送了77kb的gzip压缩版本,大多数压缩库在压缩字符串方面做得很糟糕,所以我知道它至少可以这么小。 lzma-js和gzip-js在我尝试的15个库中表现良好。
问题在于gzip-js在字符串数量上是线性的。但是,lzma正确地执行了此操作,仅在大小上略微增加。
遗憾的是,Lzma-js(级别2)在压缩7mbs(约30个字符串)时非常慢(20秒对1秒的gzip)。
是否有一个压缩库,速度大致与gzip相同,但在重复字符串上不会线性扩展?

1
你能列出你尝试过的做得不好的那些吗?这肯定会节省我们重复你已经经历过的工作的时间。 - Guy Schalnat
你看过https://dev59.com/jm455IYBdhLWcg3wCfqC的答案了吗?排名第一的答案链接到这个页面http://pieroxy.net/blog/pages/lz-string/index.html,其中引用了几个lz压缩库。 - Ed Ballot
如果您有时间,可以将比特转换为图像(每3个比特作为一个像素),并将其保存为PNG无损图像,最佳性能与非常好的压缩效果。 - S. Ali Mihandoost
https://github.com/tcorral/JSONC - Kivylius
2个回答

2

Pako 对我很有用,你也可以试试:

不要使用字符串 ID,而是使用字节数组,就像这里所做的那样。

获取 pako.js,然后你就可以像这样解压缩字节数组:

<html>
<head>
<title>Gunzipping binary gzipped string</title>
<script type="text/javascript" src="pako.js"></script>
<script type="text/javascript">

// Get datastream as Array, for example:
var charData    = [31,139,8,0,0,0,0,0,0,3,5,193,219,13,0,16,16,4,192,86,214,151,102,52,33,110,35,66,108,226,60,218,55,147,164,238,24,173,19,143,241,18,85,27,58,203,57,46,29,25,198,34,163,193,247,106,179,134,15,50,167,173,148,48,0,0,0];

// Turn number array into byte-array
var binData     = new Uint8Array(charData);

// Pako magic
var data        = pako.inflate(binData);

// Convert gunzipped byteArray back to ascii string:
var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

// Output to console
console.log(strData);

</script>
</head>
<body>
Open up the developer console.
</body>
</html>

运行示例:http://jsfiddle.net/9yH7M/

或者,您可以在将数组发送为JSON或XML时对其进行base64编码,因为数组会占用大量的开销。解码方式如下:

// Get some base64 encoded binary data from the server. Imagine we got this:
var b64Data     = 'H4sIAAAAAAAAAwXB2w0AEBAEwFbWl2Y0IW4jQmziPNo3k6TuGK0Tj/ESVRs6yzkuHRnGIqPB92qzhg8yp62UMAAAAA==';

// Decode base64 (convert ascii to binary)
var strData     = atob(b64Data);

// Convert binary string to character-number array
var charData    = strData.split('').map(function(x){return x.charCodeAt(0);});

// Turn number array into byte-array
var binData     = new Uint8Array(charData);

// Pako magic
var data        = pako.inflate(binData);

// Convert gunzipped byteArray back to ascii string:
var strData     = String.fromCharCode.apply(null, new Uint16Array(data));

// Output to console
console.log(strData);

运行示例:http://jsfiddle.net/9yH7M/1/

如需更高级的功能,请阅读pako API文档


1
使用高压缩级别的gzip-js库
https://github.com/beatgammit/gzip-js
var gzip = require('gzip-js'),
    options = {
        level: 9,
        name: 'hello-world.txt',
        timestamp: parseInt(Date.now() / 1000, 10)
    };

// out will be a JavaScript Array of bytes
var out = gzip.zip('Hello world', options);

我发现这种方式可以在正常持续时间内实现最小化大小。
至于基于LZ的压缩算法,我认为lz-string更快。请在您的数据样本上检查此内容。 https://github.com/pieroxy/lz-string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接