Gzip 和缩小

前几天,我和喜欢使用 Gzip 的人讨论了缩小 Javascript 和 CSS 的问题。

我会叫这个人 X。

X 说 Gzip 已经缩小了代码,因为它压缩了你的文件。

我不同意。Zip 是一种收缩文件大小的 毫无损失方法。无损耗意味着原件必须被完美地恢复,意味着信息必须被存储,以便能够恢复空格、不需要的字符、注释代码和其他所有东西。这占用了更多的空间,因为必须压缩更多的空间。

我没有测试的方法,但是我相信这段代码的 Gzip:

.a1 {
background-color:#FFFFFF;
padding: 40px 40px 40px 40px;
}

仍然比这段代码的 Gzip 大:

.a1{body:background-color:#FFF;padding:40px}

有人能证明这是对是错吗。请不要过来说“这是正确的,因为这是我一直使用的”。

我要的是科学证据。

36507 次浏览

这很容易测试: 只需将 css 文本放入文本文件中,然后使用类似 linux 上的 gzip 这样的归档程序压缩文件。

我刚刚做了这个,碰巧对于第一个 css,大小是184字节 第二个是162字节。

因此,您是对的,即使对于 gzip 文件,空白也很重要,但是从这个小测试可以看出,对于非常小的文件,压缩文件的大小可能大于原始文件的大小。

这是由于您的示例的大小非常小,对于较大的文件,gzip 将得到较小的文件。

有一个非常简单的测试方法: 创建一个只包含空格和另一个真正为空的文件的文件。然后 Gzip 两者并比较它们的大小。包含空格的文件当然会更大。

当然,保留布局或其他重要内容、删除不需要的垃圾内容(空白、注释、冗余内容等)的“人工”有损数据压缩比无损的 gZip 压缩要好。

例如,标记或函数名之类的东西很可能具有一定的长度来描述其含义。用名字替换一个字符可以节省很多空间,但是用无损数据压缩是不可能的。

顺便说一下,对于 CSS,有像 CSS 压缩机这样的工具可以为您做有损的工作。

然而,当你把“有损优化”和无损数据压缩结合起来的时候,你会得到最好的结果。

为什么不两个都用呢?

很容易测试。我把你的 Js 放到不同的文件里然后运行 gzip-9。这是结果。这是在运行 Cygwin 和 gzip 1.3.12的 WinXP 机器上完成的。

-rwx------  1 xxxxxxxx mkgroup-l-d     88 Apr 30 09:17 expanded.js.gz


-rwx------  1 xxxxxxxx mkgroup-l-d     81 Apr 30 09:18 minified.js.gz

下面是一个使用实际 JS 示例的进一步测试。源文件是“ common.js”,原始文件大小为73134字节。缩小到26232字节。

原始文件:

-rwxrwxrwx 1 xxxxxxxx mkgroup-l-d 73134 Apr 13 11:41 common.js

缩小档案:

-rwxr-xr-x 1 xxxxxxxx mkgroup-l-d 26232 Apr 30 10:39 common-min.js

原始文件 gzip 带 -9选项(与上面的版本相同) :

-rwxrwxrwx 1 xxxxxxxx mkgroup-l-d 12402 Apr 13 11:41 common.js.gz

缩小文件 gzip 与 -9选项(相同的版本,以上) :

-rwxr-xr-x 1 xxxxxxxx mkgroup-l-d  5608 Apr 30 10:39 common-min.js.gz

正如您所看到的,各种方法之间存在明显的差异。最好的办法是同时缩小和 gzip 它们。

你说得对。

缩小和 gzip 是不一样的(如果是这样的话,它们也可以被称为相同的缩小)。例如,这与 gzip 是不一样的:

var myIncrediblyLongNameForThisVariableThatDoesNothingButTakeUpSpace = null;

而不是缩小成这样:

var a = null;

当然,在大多数情况下,我认为最好的方法是先缩小 FIRST,然后再缩小 Gzip,而不仅仅是缩小或者 Gzip,尽管有时候根据代码的不同,只是缩小或者 Gzip 会比同时缩小或者 Gzip 给你带来更好的结果。

当然,您可以测试-写入到一个文件和 gzip 它与 Zlib。您还可以尝试使用“ gzip”实用程序。

回到你的问题——源的长度和压缩结果之间没有明确的关系。关键在于“熵”(源头中每个元素的差异)。

所以,这取决于你的消息来源。例如,许多连续空间(例如,> 1000)可以压缩为与少数(例如,< 10)空间相同的大小。

这是压缩这两个文件时的结果

bytes  File
45     min.txt
73     min.gz


72     normal.txt
81     normal.gz

你是正确的,缩小 + gzip 结果在更少的字节。虽然没有科学证明。

你怎么没有测试的方法?

在一个文件中缩小代码,并在另一个文件中保留“未缩小”的代码。上传到能够压缩输出的 webserver (例如,Apache 的 mod _ flate) ,为 firefox 安装 Firebug 扩展,清除缓存并访问这两个文件。Firebug 的“ NET”标签将包含确切的数据传输量,比较这些和你有“经验”证明。

测试的时候要小心: 这两个 CSS 片段非常小,所以它们不能从 GZIP 压缩中获益——仅仅添加 GZIP 的小头和脚(大约20字节的开销)就会失去所获得的收益。实际上,您不会有这么小的 CSS 文件,并且需要考虑压缩它。

Minify + gzip 压缩的不仅仅是 gzip

最初的问题的答案是,是的,minify + gzip 将获得比 gzip 更多的压缩。对于任何重要的示例(即任何有用的超过几百字节的 JS 或 CSS 代码)都是如此。

对于这种效果的例子,获取 Jquery 源代码是可用的缩小和未压缩的,用 gzip 压缩它们并查看一下。

值得注意的是,JavaScript 从简化中获得的好处比优化的 CSS 多得多,但仍然有一个好处。

推理:

GZIP 压缩是无损的。这意味着它必须存储所有文本,包括精确的空格、注释、长变量名等等,以便以后可以完美地复制它们。另一方面,缩小是有损耗的。如果缩小代码,就会从代码中删除大部分此类信息,从而减少 GZIP 需要保留的内容。

  • 缩小会丢弃不必要的空格,只在需要的地方留下空格。
  • 缩小删除注释。
  • 在没有副作用的情况下,代码缩小可以用较短的名称替换标识符名称。
  • 代码缩小可能会对代码进行微不足道的“编译器优化”,而这只有通过实际解析代码才有可能实现
  • CSS 缩小可以消除冗余的规则或组合具有相同选择器的规则。

下面是我不久前做的一个测试的结果,使用的是我网站上的一个“现实生活中”的 CSS 文件。CSS 优化器用于缩小。Ubuntu 附带的标准 Linux 归档应用程序用于 Gzip。

原件: 28,781字节
缩小: 22,242字节
Gzip: 6969字节
最小 + Gzip: 5990字节

我个人的观点是首先使用 Gzipping,因为这显然会带来最大的不同。至于缩小,这取决于您如何工作。您必须保留原始的 CSS 文件,以便进一步进行编辑。如果在每次改变之后都缩小它不会让你感到困扰,那么就去做吧。

(注意: 还有其他解决方案,比如在提供文件时通过“随需应变”运行它,并将它缓存到文件系统中。)

Gzip 编码有一个优势阈值。一般规则是: 文件越大,压缩和 gzip 就越好。当然,您可以先缩小,然后再缩小 gzip。

但是,如果我们讨论的是 gzip 与缩小一小段不超过100字节长度的文本,那么“客观”的比较是不可靠的,甚至是毫无意义的——除非我们拿出一个基准文本来建立一个标准的基准测试方法,比如 Lorem Ipsum 类型,但是用 Javascript 或 CSS 编写。

因此,让我建议使用我的 无脂缩小(PHP)代码来测试 jQuery 和 MooTools 的最新版本(未压缩版本)(只是简单地去掉空格和注释,不缩短变量,不使用 baseX 编码)

下面是 minify 与 gzip (在保守的5级压缩中)与 minify + gzip 的比较结果:

MooTools-Core
-------------
Baseline 102,991 bytes
Minified 79,414 (77.1% of original)
Gzipped 27,406 (26.6%)
Minified+Gzipped 22,446 (21.8%)


jQuery
------
Baseline 170,095
Minified 99,735 (58.6% of original)
Gzipped 46,501 (27.3%)
Minified+Gzipped 27,938 (16.4%)

在任何人开始之前,这不是一场 JS 库之战。

正如您所看到的,缩小 + gzip 可以提供更好的压缩 大文件。缩小代码有其优点,但主要因素是原始代码中有多少空格和注释。在这种情况下,jQuery 具有更多的内容,因此可以进行更好的缩减(内联文档中有更多的空格)。Gzip 压缩的强度在于内容中有多少重复。所以这不是缩小和 gzip 的问题。他们做事方式不同。你可以同时使用这两种方法来获得两个世界的最佳结果。

我没有看到任何人提到曼格林,所以我张贴我的结果上。

下面是我使用 UflifyJS 缩小和 Gzip 得到的一些图。我有大约20个文件,我连接在一起,大约2.5 MB 的注释和所有。

连接文件2.5 MB

uglify({
mangle: false
})

不损坏的小型化: 929kb

uglify({
mangle: true
})

缩小和损坏: 617kb

现在,如果我把这些文件和 gzip 他们我将获得239kb 和190kb 分别。