Gzip 与缩小

Posted

技术标签:

【中文标题】Gzip 与缩小【英文标题】:Gzip versus minify 【发布时间】:2010-10-22 20:51:55 【问题描述】:

前几天,我与喜欢使用 Gzip 的人进行了一次关于缩小 javascript 和 CSS 的热烈讨论。

我会称这个人为 X。

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

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

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

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

仍然会比这段代码的 Gzip 大:

.a1body:background-color:#FFF;padding:40px

有没有人可以证明这是对还是错。请不要说“这是对的,因为这是我一直使用的”。

我在这里要求科学证明。

【问题讨论】:

在查看极小的文件时尽量不要关注压缩结果。意识到 deflate 和 gzip 会产生一些开销,因此当文件大小较小时,开销的影响要大得多。 一个有效的点。不过,当上面显示的代码恰当地展示了我想要研究的原理时,我不会用数百行 CSS/JS 来让你们厌烦。 @JamesMcMahon 一个有效的观点,但不是一个答案。 需要注意的一点是缓存限制(取决于浏览器),但是一些移动浏览器会根据解压缩文件的大小进行缓存,在这种情况下,缩小是您的朋友。此外,我有一个 2meg JavaScript web 应用程序(cmets 和 reactJS 以及其他所有内容),当缩小(uglified)和 gzip(使用 zopfli 压缩)时为 75k(仅缩小大约为 200k)。 【参考方案1】:

测试非常简单。我拿走了你的 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

如您所见,各种方法之间存在明显差异。最好的办法是压缩和压缩它们。

【讨论】:

罗伯特,这是最后的选择 71k 到 26k 不是典型的缩小结果!在我的测试中,它更像是 20-25%。这似乎也是雅虎得到的:developer.yahoo.com/performance/rules.html. 缩小的大小取决于很多因素......其中之一就是你的代码被注释了多少。更多的cmets,更多的储蓄。无论如何...缩小在今天很重要,特别是因为移动用户。【参考方案2】:

这是我不久前使用我网站上的“现实生活”CSS 文件进行的一项测试的结果。 CSS Optimiser 用于缩小。 Ubuntu 附带的标准 Linux 归档应用程序用于 Gzipping。

原件:28,781 字节 缩小:22,242 字节 Gzipped:6,969 字节 Min+Gzip:5,990 字节

我个人的意见是首先选择 Gzipping,因为这显然是最大的不同。至于缩小,这取决于你的工作方式。您必须保留原始 CSS 文件才能进一步进行编辑。如果每次更改后都缩小它不打扰你,那就去吧。

(注意:还有其他解决方案,例如在提供文件时通过压缩器“按需”运行它,并将其缓存在文件系统中。)

【讨论】:

您可以获得 14% 的额外节省。这也与 Steve Souders 的结果一致。在他的“高性能网站”一书中,他有一个关于 gzip 与缩小的部分。 (第 10 章,第 74 页)他从 85K(原始)、68K(仅 JSMin)、23K(仅 gzip)到 19K(JSMin + gzip)。由于缩小,大约节省了 20%。 现在也有源图,如果你选择缩小,你可以尝试两全其美。【参考方案3】:

测试时请注意:这两个 CSS 的 sn-ps 非常小,因此它们无法从 GZIP 压缩中受益 - 仅添加 GZIP 的小页眉和页脚(大约 20 字节开销)将失去所获得的收益.实际上,您不会有这么小的 CSS 文件并担心压缩它。

minify+gzip 不仅仅压缩 gzip

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

对于这种效果的示例,grab Jquery source code 可用压缩和未压缩,使用 gzip 压缩它们并查看。

值得注意的是,与经过优化的 CSS 相比,Javascript 从缩小中获益更多,但仍然有好处。

推理:

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

缩小会丢弃不必要的空格,仅在出于语法原因需要的地方留下空格。 缩小会删除 cmets。 代码缩小可以用更短的名称替换标识符名称,这样不会产生副作用。 代码缩小可能会对代码进行微不足道的“编译器优化”,而这只能通过实际解析代码来实现 CSS 缩小可以消除冗余规则或合并具有相同选择器的规则。

【讨论】:

【参考方案4】:

你是对的。

缩小与 gzipping 不一样(如果是这种情况,它们将被称为相同)。比如gzip这个就不一样了:

var myIncrediblyLongNameForThisVariableThatDoesNothingButTakeUpSpace = null;

比缩小最终得到类似的东西:

var a = null;

当然,我认为在大多数情况下,最好的方法是先压缩 FIRST,然后再压缩 Gzip,而不是仅仅压缩或压缩,尽管有时根据代码,压缩或压缩会比两者都提供更好的结果。

【讨论】:

如何压缩 gZipped 文件?压缩良好的文件类似于随机数据,编辑它们需要提取、修改和重新压缩。 @ThorLancaster 你是对的,缩小压缩文件对我来说也没有多大意义。建议总是先缩小,然后 gzip,而不是相反。【参考方案5】:

gzip 编码是有优势的阈值。一般规则是:文件越大,压缩效果越好,gzip 会胜出。当然你也可以先缩小再gzip。

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

所以让我建议使用我的Fat-Free Minify (php) 代码对最新版本的 jQuery 和 MooTools(未压缩版本)进行基准测试(只是简单地去除空格和 cmets,不缩短变量,不使用 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 库之战。

如您所见,缩小+gzipping 可以为您提供更好的大文件压缩。缩小代码有其优势,但主要因素是原始代码中存在多少空白和 cmets。在这种情况下,jQuery 拥有更多功能,因此可以提供更好的缩小效果(内联文档中有更多的空格)。 Gzip 压缩的优势在于内容中有多少重复。因此,这与缩小与 gzip 无关。他们做事不同。并且你可以通过使用两者来获得两全其美。

【讨论】:

【参考方案6】:

为什么不同时使用?

【讨论】:

有时缩小然后 gzipping 比只做其中一个的结果更差。事实上,正如 Madewulf 所测试的,压缩纯 CSS 示例文件会得到比原始文件更大的文件! 这通常取决于文件大小。生产中的任何 CSS 和 JS 文件都将受益于缩小和压缩。如果您有大量小于 1KB 的文件,请将它们组合在一起,然后压缩并 gzip...【参考方案7】:

测试很容易:只需将 css 的文本放入文本文件中,然后使用 linux 上的 gzip 之类的存档器压缩文件。

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

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

这只是由于您的示例很小,对于较大的文件,gzipping 会得到较小的文件。

【讨论】:

在这种情况下...我更喜欢纯 CSS 文件!哇,184 字节的信息…… 您可以在 linux 上只使用 gzip outfile(或者更好的是 gzip 7-zip 与 gzip 的算法不同。【参考方案8】:

我没有看到有人提到 Mangling,所以我将我的结果发布在上面。

以下是我使用 UflifyJS 进行压缩和 Gzip 得出的一些数字。我有大约 20 个文件,我用 cmets 和所有文件以大约 2.5MB 的大小将它们连接在一起。

连接文件 2.5MB

uglify(
    mangle: false
)

没有修改的缩小:929kb

uglify(
    mangle: true
)

缩小和损坏:617kb

现在,如果我将这些文件压缩并压缩,我将分别得到 239kb 和 190kb。

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

当然,保留布局或其他一些重要内容并删除任何不需要的垃圾(空格、cmets、冗余内容等)的“人工”有损压缩比无损 gZip 压缩要好。

例如,标记或函数名称之类的东西很可能有一定的长度来描述含义。将其替换为一个字符长的名称将节省大量空间,并且在无损压缩中是不可能的。

顺便说一句,对于 CSS,有像 CSS compressor 这样的工具可以为您完成有损工作。

但是,当结合“有损优化”和无损压缩时,您将获得最佳结果。

【讨论】:

【参考方案11】:

当然,您可以测试 - 将您的文件写入文件并使用zlib 对其进行 gzip 压缩。您也可以尝试使用“gzip”实用程序。

回到您的问题 - 源的长度和压缩结果之间没有明确的关系。关键是“熵”(源中的每个元素有多么不同)。

所以,这取决于您的来源。例如,许多连续的空格(例如,> 1000)可能会被压缩为与少数(例如,

【讨论】:

【参考方案12】:

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

bytes  File
45     min.txt
73     min.gz

72     normal.txt
81     normal.gz

【讨论】:

@madewulf,只有当文件如此之小和微不足道以至于 GZIP 文件头的附加实际上比节省空间更重要时,才会出现这种情况。在实践中没有人会使用这么小的 CSS 文件,或者如果他们这样做了,那么压缩它不应该是他们首先关心的问题。无论如何,它仍然表明缩小 + gzipping 比仅 gzipping 更有效,这当然是正确的。【参考方案13】:

你是对的,minify+gzip 会减少字节数。但没有科学证据。

你怎么没有测试方法?

在一个文件中缩小您的代码,并将其“未缩小”留在另一个文件中。上传到能够对输出进行 gzip 压缩的网络服务器(例如,用于 Apache 的 mod_deflate),为 firefox 安装 Firebug 扩展,清除缓存并访问这两个文件。 Firebug 的“NET”选项卡将包含传输的确切数据量,比较这些数据,您就有了“经验”证明。

【讨论】:

以上是关于Gzip 与缩小的主要内容,如果未能解决你的问题,请参考以下文章

运行我的应用程序时出现 Angular2 GZIP 问题

Spring gzip 与 Tomcat gzip

WEB性能调优:gzip 与 chunked

mod_deflate 与 mod_gzip

Flutter Gzip 编码与解码 Dart Gzip 工具类操作

GZIP 与 DEFLATE 压缩相比有啥优势?