Gzip与压缩的比较

138

我前几天就JavaScript和CSS文件的压缩问题与一个更喜欢使用Gzip的人进行了相当热烈的讨论。

为方便叙述,我将此人称为X。

X认为Gzip已经对代码进行了最小化处理,因为它压缩了你的文件。

我不同意。Zip是一种无损缩小文件大小的方法。无损意味着原始数据必须完美恢复,这意味着必须存储信息以使得空格、不需要的字符、注释代码以及其他所有东西都能被恢复。这需要占用更多的空间,因为需要压缩更多内容。

我没有测试的方法,但我相信对于以下代码的Gzip:

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

这段代码的 Gzip 压缩后仍然比此处的大小更大:

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

有没有人能够证明这个观点的正确性或错误性。
请不要说“它是正确的,因为这是我一直使用的”。

我在这里是在寻求科学证明。


50
查看极小文件时,尽量不要关注压缩结果。请注意,deflate和gzip会产生一些开销,因此当文件大小很小时,开销的影响会更大。请理解这一点。 - Min
9
有道理。然而,我不打算用成百上千行的CSS / JS来把你们搞得烦死,因为上面展示的代码已经很好地展示了我想要研究的原理。 - KdgDev
@JamesMcMahon 有道理,但不是答案。 - Abby Chau Yu Hoi
值得注意的一件事是缓存限制(它因浏览器而异),但某些移动浏览器基于未压缩文件大小进行缓存,在这种情况下,代码压缩是您的好朋友。此外,我有一个2兆字节的JavaScript Web应用程序(包括评论、ReactJS和其他所有内容),当经过代码压缩(Uglify)和Gzip压缩(使用Zopfli压缩)后,大小为75k(仅代码压缩大约为200k)。 - vipero07
13个回答

201

测试非常简单。我将您的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

使用-9选项压缩的原始文件(与上面版本相同):

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

使用 -9 选项压缩后的被最小化文件(与上述版本相同):

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

正如您所看到的,这些方法之间存在明显的差异。最好的办法是将它们压缩并使用gzip。


9
罗伯特,那是最后的选择。 - Chuck Vose
6
71千字节到26千字节的缩小并不是典型的缩小结果!在我的测试中,通常只有20-25%左右。这似乎也是雅虎得出的结论:http://developer.yahoo.com/performance/rules.html。 - Deepak
2
代码压缩的缺点取决于许多因素...其中之一是您的代码有多少注释。注释越多,节省的空间就越多。无论如何...代码压缩在今天尤其重要,特别是对于移动用户。 - Alex Benfica

29
这里是我之前做的一个测试结果,使用了我网站上的一个“真实”的CSS文件。使用CSS Optimiser 进行了最小化处理。Ubuntu自带的标准Linux归档应用程序用于Gzip压缩。
原始大小:28,781字节
最小化后大小:22,242字节
Gzip压缩后大小:6,969字节
最小化和Gzip压缩后大小:5,990字节

我的个人意见是首先进行Gzip压缩,因为这显然会产生最大的差异。至于最小化处理,则取决于你的工作方式。如果您想要在以后继续编辑,则必须保留原始CSS文件。如果每次更改后都不介意对其进行最小化处理,请尽管这样做。
(注意:还有其他解决方案,例如在提供文件时通过“按需”运行它来进行最小化处理,并将其缓存到文件系统中。)

您可以获得额外14%的节省。这也与Steve Souders的结果相符。在他的书《高性能网站》中,他有一节关于gzip与缩小的比较。(第10章,第74页)他从85K(原始大小),68K(仅JSMin),23K(仅gzip),到19K(JSMin + gzip)。由于缩小,大约节省了20%的空间。 - Deepak
2
现在有源代码映射,如果你选择缩小文件,它们可以让你尝试兼顾两者的优点。 - jeteon

16

注意测试时要小心:这两个 CSS 片段非常简短,因此它们不会受益于 GZIP 压缩——仅添加 GZIP 的一个小标题和页脚(约 20 字节的开销)就足以抵消收益。实际上,您不会有这么小的 CSS 文件并担心压缩它。

Minify+Gzip 比仅使用 Gzip 压缩更多

对于任何非平凡的示例(即任何有用的 JS 或 CSS 代码超过几百字节),答案是肯定的。通过 minify+gzip 可以获得比仅使用 gzip 更多的压缩效果。

如果想看到这种效果的实例,请下载 JQuery 源代码,该源代码提供了经过压缩和未压缩的版本,将它们都使用 gzip 压缩后对比一下。

值得注意的是,与精心优化的 CSS 相比,JavaScript 更容易受益于代码缩小,但 CSS 也有所改善。

原因如下:

GZIP 压缩是无损的。这意味着它必须存储所有文本,包括精确的空格、注释、长变量名等,以便稍后可以完全重现它们。另一方面,代码缩小是有损的。如果您缩小了代码,则会从代码中删除其中许多信息,留下 GZIP 需要保留的内容更少。

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

12

你说得没错。

压缩和gzip压缩不同(如果是同一种方法的话,它们就会被称为相同的)。例如,对于以下内容进行gzip压缩并不相同:

var myIncrediblyLongNameForThisVariableThatDoesNothingButTakeUpSpace = null;

然后进行缩小以得到如下内容:

var a = null;

当然,在大多数情况下,我认为最好的方法是先进行代码压缩(minify),然后再进行Gzip压缩,而不是仅仅进行代码压缩或者Gzip压缩;虽然根据代码的不同,有时候只进行代码压缩或者Gzip压缩会比两种都做要更好。


压缩后的文件看起来像随机数据,编辑它们需要先解压、修改,再重新压缩。那么对于一个已经被压缩过的 gZipped 文件进行缩小会是怎样的呢? - Thor Lancaster
@ThorLancaster 您是正确的,对我来说,缩小已经压缩的文件没有太多意义。建议总是先缩小,然后再进行gzip压缩,而不是反过来。 - Seb

8
在gzip编码有优势的阈值上,通常规则是:文件越大,压缩效果越好,gzip会轻松获胜。当然,您可以先进行代码精简,然后再进行gzip压缩。
但是,如果我们在一个小于100字节的文本片段上进行gzip与代码精简的比较,那么“客观”的比较是不可靠的,甚至是无意义的 - 除非我们使用类似于JavaScript或CSS中的Lorem Ipsum类型的基准文本来建立标准的基准测试方法。
因此,让我提议使用最新版本的jQuery和MooTools(未压缩版本),使用我的Fat-Free Minify(PHP)代码(只是简单地删除空格和注释,不缩短变量,不进行baseX编码)来进行基准测试。
以下是代码精简与gzip(保守级别5压缩)与代码精简+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库之前,需要说明的是这不是JS库之间的竞争。
如你所见,对于大文件而言,压缩和gzip可以提供更好的压缩效果。代码的压缩有其优点,但主要因素取决于原始代码中存在多少空白和注释。在这种情况下,jQuery具有更多的空白,因此提供更好的压缩效果(内联文档中有更多的空白)。 Gzip压缩的强度在于内容中有多少重复。因此,这不是压缩与gzip之间的比较,它们以不同的方式处理内容。使用两者可以同时获得最佳效果。

5
为什么不两者兼顾呢?

1
有时候,缩小文件大小再进行gzip压缩的效果比仅执行其中一个操作更糟糕。实际上,正如madewulf所测试的那样,对于纯CSS示例文件进行gzip压缩会得到比原始文件更大的文件! - Seb
4
通常这取决于文件大小。在生产中,所有CSS和JS文件都会受益于缩小和压缩。如果你有很多小于1KB的文件,请将它们合并在一起,然后进行缩小和gzip压缩... - Min

1

我没有看到任何人提到Mangling,所以我在这里发布我的结果。

以下是我使用UflifyJS进行最小化和Gzip压缩得出的一些数字。我有大约20个文件,将它们连接在一起,包括注释,总大小约为2.5MB。

连接文件2.5MB

uglify({
    mangle: false
})

未混淆的压缩版本大小为929kb

uglify({
    mangle: true
})

经过压缩和混淆后:617kb

现在,如果我将这些文件进行gzip压缩,分别可以得到239kb和190kb。


1

测试很容易:只需将CSS文本放入文本文件中,并使用类似于Linux上的gzip的压缩程序压缩文件。

我刚刚做了这个,结果第一个CSS的大小为184字节,第二个CSS的大小为162字节。

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

这仅是由于您的示例非常小,对于较大的文件,压缩将使文件更小。


在这种情况下,我更喜欢使用普通的CSS文件!哇,仅仅184个字节就能包含那么少的信息... - Seb
在Linux上,您可以使用“gzip < infile > outfile”(或更好的是,“gzip < infile | wc”)来压缩文件。tar存储了大量元数据。 - phihag
1
7-zip不是gzip相同的算法。 - vartec

0

这是对两个文件进行gzip压缩后的结果

bytes  File
45     min.txt
73     min.gz

72     normal.txt
81     normal.gz

2
@madewulf,这只是在文件非常小且琐碎的情况下才会出现,此时GZIP文件头的添加实际上比节省空间更重要。在实践中,没有人会使用如此小的CSS文件,或者如果他们确实使用了,那么压缩它不应该是他们的首要关注点。无论如何,这仍然表明,压缩+ GZIP比仅仅使用GZIP更高效,这当然是正确的。 - thomasrutter

0

有一种非常简单的测试方法:创建一个仅包含空格的文件和另一个真正为空的文件。然后将它们都压缩并比较它们的大小。当然,带有空格的文件会更大。


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