这些都是您对网站上的资源(例如 .css 文件和 .js 文件)执行的操作。 它们都能够减小文件大小,从而提高服务器和浏览器之间网络传输的效率。 简而言之,有利于性能提升。 网络是 Web 的速度瓶颈,减小文件大小有助于提升速度。
但这两种操作截然不同。 如果你之前不知道这一点,那么理解它们之间的区别很有必要。
压缩会执行以下操作:删除空格、删除注释、删除不必要的分号、缩短十六进制代码长度……
……等等。 文件仍然是完全有效的代码。 您可能不希望尝试阅读或使用它,但它并没有违反任何规则。 浏览器可以像读取原始文件一样读取和使用它。
压缩会创建一个您最终使用的新的文件。 例如,您可以创建一个 `style.css` 文件来进行工作。 然后您可以将其压缩成 `style.min.css`。
Gzip 会查找所有重复的字符串,并用指向该字符串第一次出现的指针替换它们。
Julia Evans 创建了一种绝妙的方法来理解这一点(请参阅她的 文章和视频)。 请看这首诗的第一段
在一个漆黑的午夜,当我 {pon}dered weak an{d wea}{ry,}
翻阅许多{ a }quaint{ and }curious 遗忘的知识的书籍,
W{hile I }nodded, n{ear}ly napping, su{dde}n{ly }th{ere} ca{me }a t{apping,}
As{ of }so{me o}ne gent{ly }r{apping, }{rapping} at my chamb{er }door.
`’Tis{ some }visitor,’{ I }mu{tte}r{ed, }`t{apping at my chamber door} –
O{nly th}is,{ and }no{thi}{ng }m{ore}.
花括号内的文本已被 gzip 发现是重复的。 因此,将用占用空间更小的指针替换它。
这对于减少文件大小非常有效,尤其是在代码中,因为代码可能非常重复。 想象一下 HTML 文件中有多少个 <div
实例或 CSS 文件中有多少个 {
实例。
您可以创建文件的 gzip 版本(即 style.css.zip),但**您几乎从不这样做**,并且**浏览器也不知道如何处理它**。
在 Web 上,Gzip 是由您的服务器直接执行的。 这需要配置服务器才能执行此操作。 完成此操作后,Gzip 会自动发生,您无需执行任何其他操作。 服务器会压缩文件并以这种方式将其发送到网络。 浏览器接收文件并在使用前对其进行解压缩。 我从未听说过有人提到压缩和解压缩的开销,因此我只是假设它可以忽略不计,并且好处远远大于开销。
以下是如何在 Apache 服务器上启用它,它使用 `mod_deflate` 模块。 并且 H5BP 提供了所有流行服务器的服务器配置,其中包括 Gzip。
示例
我们将使用来自 Bootstrap 的 CSS 文件,因为它是一个非常常见的资源。

压缩 CSS 可以节省大约 17% 的空间,Gzip 可以节省 85% 的空间,或者如果同时使用两者,则可以节省 86% 的空间。
以下是检查 DevTools 中所有内容是否正常工作的理想情况

Gzip 的效果要好得多。 同时使用两者是理想的选择。
Gzip 使文件大小减少了大约五倍。 但是,您也可以从压缩中获得 一些 提升,并且由于它可能在构建步骤中几乎不需要额外的努力,因此您不妨一试。
也有一些 证据 表明浏览器可以更快地读取和解析压缩的文件
正如预期的那样,除了网络传输时间之外,压缩还有助于解析和加载。 这可能是由于缺少注释和额外空格造成的。
微软也开始 优化其解析器
因此,在 Windows 10 和 Microsoft Edge 中,我们添加了新的快速路径,改进了内联并优化了 Chakra JIT 编译器中的一些启发式算法,以确保压缩代码的运行速度与非压缩版本一样快,甚至更快。 通过这些更改,我们测试过的使用 UglifyJS 压缩的单个代码模式的性能提高了 20% 到 50%。
缓存资源也与此对话相关,因为没有什么比浏览器根本不需要请求资源更快了! 网上(或书籍中)有大量关于此的信息,但我们可能很快就会发布一篇关于此的文章,其中包含一些技巧。
还有第三种选择值得讨论:使用 JavaScript 压缩 JavaScript 文件。
源脚本将使用 gzip、lha 等知名方法进行压缩。
然后,生成的字符串将用作解压缩 JavaScript 函数的参数。 这非常有效,因为许多解压缩算法都非常易于实现。
与服务器原生 Gzip 压缩相比,这可能看起来毫无意义。 在 SEO 机器人方面变得有趣:如果这些机器人衡量解压缩后的有效负载,您可能会领先几步。 另一方面,此方法会在浏览器端产生运行时开销,最终会导致更差的总页面加载时间。
无论如何,这在技术上很有趣,而且正如我所说,应该进行讨论。
在工作中,我们一直在与 SEO 团队讨论这个问题,因为只有神才知道 Google 究竟是如何真正解读您的网站的。
并且您将在下次页面访问时丢失缓存……
嘿,感谢您撰写本文! 实用的知识。
对于我自己的网站,我还没有费心进行压缩——它更像是一个技术实验,所以在那里这样做是有意义的。 我不介意让人们看到我如何编写我的网站,如果我要向某人展示该网站并遇到问题,我希望能够在任何地方进行调试,虽然源映射极大地缓解了这个问题,但它们仍然不完美。 它还省去了构建步骤。(也就是说,对于大型网站,这样做肯定是有意义的)
如果您希望这样做,您可以提供一个源映射文件,该文件可以使用 Gulp/Grunt 等自动生成,此外,在 Chrome 开发者工具中,当您查看压缩的 CSS 文件(或压缩的 JS 文件)时,您可以单击窗口左下角的 {} 按钮,它将为您美化文件……
由于大多数人都会在开发者工具中调试您的页面,因此没有必要因为开发者工具会解压缩您的代码而放弃压缩。
您也可以仅在生产部署中运行压缩任务,并配置服务器仅在生产环境中使用 gzip 压缩。
开发者工具不会“解压缩”任何内容。它确实允许您访问 DOM 和样式,但 DOM 通常使用 JavaScript 构建,因此您无法看到原始的未压缩标记。此外,开发者工具在任何意义上都不会解压缩您的 JS,这可能是人们在想知道您的网站是如何构建时想要看到的内容。其他大多数内容都是微不足道的。
仅供参考,压缩可以(并且会)减少页面加载时间。下载的数据越少,下载速度就越快。它不会花费您任何费用,并且只需几分钟即可正确设置。而且,正如已经说过的,现在是 2015 年,如果有人想调试您的代码,无论它是否已压缩,他都会这么做。
需要注意的一点是,在涉及机密信息时,在 HTTPS 连接上使用 gzip 压缩是大忌。无法缓解这些攻击,因此应完全关闭所有类型的压缩以确保连接安全。
也就是说,只有当压缩流中存在机密信息时,这才是个大问题。因此,如果您只是从不包含会话 Cookie(或标头中的其他机密信息)的单独域名提供 CSS 和通用 JavaScript,那么这样做是没问题的。只需确保不要在提供 HTML 的域名上使用 gzip 压缩——尤其是在同时提供 Cookie 或文档中包含任何形式的机密信息的情况下。
并非所有环境都容易受到 CRIME 攻击。例如,请参阅同一维基百科文章中的缓解措施部分。
混淆呢?
通常,JavaScript 的压缩也称为“混淆”,因为它使代码非常难以阅读。
存在 JavaScript 混淆,它与压缩不同:当后者试图缩减代码时,前者则会添加代码以使其更难以阅读。
例如,即使压缩重命名了所有变量,这些变量也可以手动或使用 jsnice.org 等工具进行统计重命名。另一方面,混淆会将您的代码包装在一个由 eval 结构、浏览器环境检查和
setInterval('debugger')
组成的巨大混乱中,以便在您使用开发者工具时让您感到烦恼。此外,这只是一个例子,压缩和混淆工具可以以其他方式工作,因此您的里程可能会有所不同。
毫无疑问,压缩虽然不是其唯一目的,但它确实是混淆的一种形式。
只想在这方面发表一下意见
这几乎总是正确的,除非您有一个非常大的文件。假设您完全用 JavaScript 编写了一个游戏,并且您的文件非常庞大。或者更糟糕的是,也许您用另一种语言编写了游戏,然后将其编译成 JavaScript(请参阅Emscripten等)。
在这种情况下,您可能会发现提前压缩文件并将 Web 服务器配置为直接提供压缩文件(当然,还要使用相应的 Content-Type 标头)是有益的。这将减少每次有人加载页面时 Web 服务器需要执行的工作量(当然,这也可以通过其他方式来缓解,例如使用浏览器缓存)。
您可以在 Apache 中使用类似以下内容来做到这一点(根据SO 上的此答案)
这些规则基本上表示“使用
text/css
内容类型提供.css.gz
文件,并确保不要压缩它们(因为它们已经压缩了)。.js.gz
文件也是如此。除此之外,我完全同意这篇文章。压缩您的(文本)资源!
但通过包含“很少”一词,他的意思是 gzip 压缩实际上偶尔会被执行。因此,语句“您可以创建文件的 gzip 版本(即 style.css.zip),但您很少这样做,并且浏览器也不知道该怎么处理它”是完全正确的。
不错的评论,Agop,我一直想知道在什么情况下您会直接提供压缩文件。 :)
在 Nginx 配置文件中添加以下内容以启用 gzip 压缩
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
请注意,gzip_comp_level 的取值范围为 0-9。较高的值表示更高的压缩率,但需要更多的资源来计算。级别 5 或 6 通常是最佳选择。
某些主机不允许动态 gzip 压缩(例如 Amazon Web Services 或 NearlyFreeSpeech.NET),这意味着根据环境,最终可能会出现
styles.min.css.gz
等文件。虽然这有点令人沮丧,但它确实会使最终用户体验更快服务器不会花费任何时间压缩文件
由于您已经提前进行了压缩,因此您可以使用最大压缩率对文件进行 gzip 压缩,这可以节省一些额外的百分比并减少解压缩时间(gzip 在压缩技术中是不寻常的,因为它压缩得越厉害,膨胀速度就越快)。
哎呀,如果这是一个流量很大的文件,您可以继续使用 zopfli 压缩它,这需要花费很长时间,但最终可以得到尽可能小的文件。
由于我的主机,我必须“预压缩”所有内容,但存储空间很便宜。只需少量
.htaccess
配置即可让 Apache 在发送Accept-Encoding
时使用.gz
版本。对于 SVG 文件来说,这一点变得更好,因为任何符合标准的 SVG 查看器都必须处理 SVGZ 文件。我的测试表明,所有浏览器(甚至 IE9!)都确实符合标准,因此我根本不需要包含原始的
.svg
文件。您可能想要预压缩资源的一个原因是您可以提高压缩级别。许多压缩方案允许您提供压缩级别(例如 1 – 10),该级别指定算法尝试压缩数据的力度。很多时候,Web 服务器的默认配置使用中间级别(例如 5),以尝试平衡执行压缩的 CPU 成本与通过网络节省的字节数。某些服务(如 Amazon S3)允许您上传预压缩的资源,因此您的服务器(以及它们的服务器)无需花费任何 CPU 时间来进行压缩,并且您的用户可以获得尽可能小的文件。一个基于 Java 的工具 JetS3t 使上传压缩内容变得轻而易举。构建一些自动化内容以将其融入您的工作流程有点复杂,但可以做到。
不幸的是,gzip 压缩并不能解决 IE9 限制浏览器读取 CSS 数量的无稽之谈。对吧?
只有压缩才能解决此问题。
这是由 CSS 选择器的数量而不是文件大小引起的。压缩器可能会优化样式表并减少选择器的数量,这似乎有助于解决问题,但实际上您需要的是像 blessed 这样的工具,它可以拆分您的 CSS 文件,并允许您的应用程序拥有任意数量的规则而不会出现问题 :)
必须说实话……即使是最庞大、最企业级的应用程序也不应该有那么多选择器。如果您担心达到 4k+ 选择器限制,则需要停止担心 GZIP 并开始精简您的 CSS。
对于 IE,有 2 个限制需要考虑 CSS。一个是选择器数量的限制,另一个是样式表包含数量的限制。
幸运的是,较新版本的 IE 已解决了这些问题。
如果文件小于 1500 字节,则不应压缩它。压缩已经适合 MTU 窗口的文件只会浪费连接两端的 CPU 周期。根据您执行的压缩量,最小文件大小阈值可能需要高达 5KB。
很高兴读到这篇文章。感谢你的写作和有用的评论。
我发现有点奇怪,你写了关于压缩的文章,但你自己的 HTML 却没有压缩 :)
我并不热衷于压缩 HTML。HTML 中的空格仍然有意义(例如 这里)。
好吧,你可以做一些叫做“安全压缩”的事情,其中每个空格序列都被替换为空格——结果相同。现在,看看仅仅通过将所有制表符和换行符替换为空格,你可以节省多少(字节)。
这与你对 CSS 或 JS 所做的完全相同。不,HTML 中的空格没有意义,除非它在
<pre>..</pre>
中。你应该写一篇关于所有这些内容的教程,让我可以阅读!
@Artur: 自动化 HTML 压缩的问题在于,你无法知道哪些元素具有
white-space: pre
或其他类似的选择器,这些选择器会改变空格的处理方式。这就是人们不这样做的原因。新兴的页面生成技术可能导致“压缩”的 HTML 输出。例如,在创建同构 React 站点时,就会出现这种情况:React 渲染的页面几乎没有换行符。
这些站点不能与使用压缩 HTML 的站点混淆,因为它们不是。这仅仅是 Virtual DOM 和页面生成工作方式的结果:没有模板,不需要人类格式化的标记。
@chris 哈哈,没有。
@veso 嗯,规范表示(换句话说):你想要空格——使用
<pre>
。问题是大多数开发人员不知道这一点,你可以在文章中看到类似这样的“技巧”。至于 React,从未使用过,所以我无法发表评论。有很多压缩技术需要你更改代码风格(因为压缩器只能做到如此智能),从而获得更多收益。
例如,永远不要两次引用方法名称。并使用诸如 function… { var LEN=’length’; if( a[LEN] > 2…
在任何地方使用局部变量 a[LEN] 而不是 a.length 将允许压缩器将其替换为 a[A]。然后你的代码中将有几十个 a[A](根据方法,局部 A 将是其他内容)。然后当 gzip 出现时,它将像什么都没发生一样地处理这些重复的模式!
这就是为什么你应该始终在压缩后测试你的代码,但更重要的是——你应该避免编写容易被误解或难以阅读的代码(对人和计算机而言)。
关于…的小更正
.zip
不是 gzip(除非你重命名了文件)。压缩该文件默认会给你style.css.gz
你还可以使用类似 UNCSS 的工具来处理你的 CSS,以去除你未使用的大约 90% 的 Bootstrap。
在使用像 AWS S3 这样的服务时手动压缩,然后重命名为 style.css 并上传到存储桶。如果你不设置 Content-Encoding: gzip 头部,压缩的 CSS 会发送给你的用户,这让你更清楚地了解这个头部有多重要。此外,压缩可以与 HTML 直接一起工作,但如果没有任何告诉浏览器先解压缩的头部,压缩对于浏览器来说毫无意义。
如果有人不清楚使用 CSS 源映射的好处(尤其是在使用 Sass 时很有用),我不久前写了一篇关于它的博文
http://sheelahb.com/blog/up-your-efficiency-with-zurb-foundation-css-source-maps/
如果你想窥探一下压缩文件内部,可以使用 defdb 或使用 gzthermal 生成压缩效率热图。
gzthermal
http://encode.ru/threads/1889-gzthermal-pseudo-thermal-view-of-Gzip-Deflate-compression-efficiency
defdb
http://encode.ru/threads/1428-defdb-a-tool-to-dump-the-deflate-stream-from-gz-and-png-files
如果你正在手动压缩文件,请考虑使用 zopfli 或 kzip+kzip2gz 而不是 gzip 命令,因为两者都能生成更小的文件(甚至比“gzip -9n”更小)。
例如,在 book1 文件上
312,275 字节(gzip -9n)
299,455 字节(kzip,在 zip 到 gz 转换之后)
299,504 字节 zopfli
298,695 字节 zopfli –i1000
Zopfli
https://github.com/google/zopfli
更快更好的 KrzYmod 定制版本(包含二进制文件)
http://encode.ru/threads/2176-Zopfli-amp-ZopfliPNG-KrzYmod
KZIP
http://advsys.net/ken/utils.htm
http://www.jonof.id.au/kenutils
kzip2gz
http://encode.ru/threads/1630-kzip2gz-a-zip-%28single-file-amp-deflate-compression%29-to-gz-converter
之后运行 deflopt 和/或 defluff 可以节省更多字节。
Defluff
http://encode.ru/threads/1214-defluff-a-deflate-huffman-optimizer
如果你有很多 CPU 资源和时间,你可以使用 rezop 重新压缩由 kzip+kzip2gz 生成的文件,这将保留 kzip 完成的块分割,并使用 Zopfli 算法重新压缩每个 deflate 块)最后使用 huffmix 选择最小的块。
Huffmix 是为了加快 KZIP/PNGOUT 的随机设置而编写的,如果你真的需要节省一些额外的字节,你可以循环遍历 KZIP 的随机运行,如 Huffmix 页面上所述。
Rezop
http://encode.ru/threads/2204-rezop-recompress-using-zopfli-while-preserving-blocksplit
Huffmix
http://encode.ru/threads/1313-Huffmix-a-PNGOUT-r-catalyst
这太棒了。你介意把它放在一个我可以链接到的 URL 上吗,以便其他人使用?(WordPress 评论片段可能会出现奇怪的行为。)
哦,由于它写得很大且很粗体,我必须更正这句话
“Gzipping 查找所有重复的字符串,并将其替换为指向该字符串第一次出现的指针。”
LZ 匹配通常引用最后一个实例,因为距离是相对于解码点(而不是文件开头)表示的,并且因为距离越长,记录它所需的位数就越多。
如果你不怕听法语*,我制作了一个视频来解释整个 LZ77/LZSS 以及贪婪/最优/惰性解析器之间的差异。
视频(法语)跳到 3:25,逐步解码 gzip 流
*否则,只需关闭声音并查看箭头如何指向之前的文本引用。
值得一提的是,压缩文件更有可能在浏览器缓存中停留更长时间,因为它们更小,并且不会像以前那样频繁地触发刷新。这可能只提高了 0.01% 的性能,但当你拥有数千次访问时,这将有助于防止重新请求资源。
在移动设备和 AppCache 的存储容量有限的情况下,这一点更为重要。
哦,非常好的观点。同样适用于 localStorage 缓存等。
我一直使用我关于 https://mathiasbynens.be/demo/jquery-size 的图表来解释这一点。在我看来,它很好地可视化了差异。
哇!这证明了 zopfli 被高估了。老式的 gzip 就足够了。
@Peter 不,不是的。正如你从 Mathias 的图表中看到的,他只运行了 15 次迭代。对于页面加载最重要的文件(如 css、js 等)来说,使用 zopfli 压缩文件完全值得。想想所有节省的毫秒 :D
非常棒的文章!我们为客户开发了很多 WordPress,因此我们经常使用为此预配置的插件,例如 W3 Total Cache、BWP Minify、Super Cache 等。你对这些类型的压缩和 gzip 工具有什么想法吗?
谢谢!
Larry Wolf
我之前在尝试优化一个 JSON Blob 时也有类似的发现:http://www.peterbe.com/plog/gzip-rules-the-world-of-optimization