理解和使用服务器的压缩传输功能

压缩传输是一种简单有效的节省带宽、提高网站访问速度的方式。这种方式可以工作于目前绝大多数浏览器(IE6-9、FirefoxOpera、Safari等),虽然不支持古老的 IE4 浏览器

采用这种方式可以减少用户等待的时间,大大提高你网站的用户体验,这就从另一方面使得搜索引擎更加肯定你的网站。技术发展到今天,开启 gzip 压缩已经是大势所趋。Google 和 Yahoo 早已经开始使用 gzip 压缩,百度也在较早的时候宣布支持 gzip 方式。如果你注重用户体验,或者你更加关注的是网站搜索引擎优化(SEO),就应该尽可能开启服务器上的 gzip 压缩传输方式。本文将对相关内容进行比较全面的介绍。

一、浏览网页的简化过程

在我们开始之前先来简单了解一下访问一个网站的过程。当你访问一个网站的某个页面的时候,比如访问 http://www.yahoo.com/index.html,你的浏览器就开始与服务器进行“对话”,称之为请求/响应过程,如下图 1 所示:

图1 HTTP 请求与响应过程 – 无 gzip 模式

  1. 浏览器:你好,将 /index.html 发给我吧。
  2. 服务器:好,我看看 index.html 在什么地方……
  3. 服务器:找到了,这是对你的响应代码(200 OK),现在开始发送文件。
  4. 浏览器:100KB?好吧……等待,等待……好了,加载完毕。

当然,上面只是简化后的过程,实际的文件头和协议会比较繁琐(如果你想仔细研究的话可以参考类似 TCP/IP 的计算机书籍)。

经过这个过程,你就能在浏览器里看到想要的页面内容了。

二、为什么要进行 Gzip 压缩?

既然没有开启 Gzip 我们可以无障碍的浏览网页,为什么还要进行 Gzip 压缩呢?

虽然上面的过程可行,但是效率不高。对于目前的网络条件而言,100KB 并不是个小体积。如果你的网站放在国外的服务器上,以正常 20KB/s 的速度传输也需要 5 秒钟的时间。试问,有几个用户愿意等待 5 秒钟才看到页面内容?而且,就算网速提高了,难道不是越快越好吗?

实际上,HTML 文件冗余度很高。每个 <html>,<table> 和 <div> 等等标签都有一个基本一样的闭合标签;文档中的文字有很多重复的。不只是 HTML 文件,还有 CSS,JS 等,它们都有很高的冗余度,可以被压缩到很小的体积。这跟我们通常采用 RAR 压缩方式来减小文件体积的效果一样。

如果我们能够将压缩后的文件传输给浏览器(index.html.zip 或 index.html.gzip)而不是本来的普通文件 index.html 的话,我们就能够节省带宽和下载(传输)时间。而浏览器会接收经过压缩的文件,然后解压并显示给用户。网页打开速度快了,用户的心情就会更好,也更愿意在你的网站上浏览。

这个时候,上面图 1 的过程变成下面图 2 的形式:

图2 HTTP 请求与响应过程 – gzip 模式

  1. 浏览器:你好,将 /index.html 发给我吧。如果你能提供的话,我想要压缩格式。
  2. 服务器:嗯,我看看 index.html 在什么地方……好,找到了。你想要压缩格式的?太好了。
  3. 服务器:我找到了 index.html(200 OK),正在压缩,马上就发送给你。
  4. 浏览器:太好了,只有 10KB。我来解压并显示给用户。

这很好理解:更小的文件 = 更快的传输过程 = 好的用户体验

不相信吗?我们来看看上面提到的 yahoo 首页的压缩情况:

图3 yahoo 首页的 Gzip 压缩情况

该页面原始大小 101KB,压缩后 15KB。这还仅仅是 HTML 文件压缩带来的效果,如果再加上 CSS,JS 等文件,节省的带宽和时间是很吸引人的。

三、一些细节


开启 Gzip 压缩传输功能中有个关键的一步,浏览器和服务器之间会交换信息,然后服务器知道可以发送压缩文件,然后才会发送压缩过的文件,否则就发送常规文件。这种信息交换包含 2 部分内容:

  • 浏览器发送一个文件头,告诉服务器它接受压缩文件(可以使用 gzip 或者 deflate 的方式压缩): Accept-Encoding: gzip, deflate
  • 服务器响应声明内容压缩的具体格式: Content-Encoding: gzip

如果服务器没有发送内容压缩响应,则表示文件没有被压缩(很多服务器默认是不压缩文件的)。响应头 “Accept-encoding” 是浏览器发送的一个声明,并不是必须的。如果服务器不愿意发送压缩内容,浏览器就必须按照常规方式进行处理。

由上面的说明我们可以看到,

  • 如果浏览器接受压缩传输,而服务器不支持,则按照普通方式传输文件;
  • 如果服务器支持压缩传输,而浏览器不支持,还是按照普通方式传输文件;
  • 只有浏览器和服务器双方都支持的时候才会使用压缩文件的方式传输内容。

四、配置服务器以响应压缩传输请求

目前的绝大多数浏览器都支持压缩传输,即使是手机上的浏览器也很多都支持压缩传输。但是服务器的默认设置却不是这样,所以作为网站管理员或者服务器管理员,应该考虑开启服务器上的压缩传输功能。

下面的内容是本文结论的重点所在。

1、如果你拥有服务器的配置管理权限

如果你自己有关权限能够配置服务器,不管是 Windows 服务器还是 Linux/Unix 上的服务器都支持压缩传输,你只需要配置好了就行了。

根据我的经历(也许并不是十分准确,因为我没有这样的服务器,也没有服务器配置的经验),litespeed (一个经过优化的类 Apache 服务器软件,收费)是默认支持压缩传输的,并且在该服务器上如果额外设置压缩传输(象在 Apache 服务上所做的那样)会导致浏览器访问错误而造成乱码

但是对于主流的 Windows 上的 IIS 服务器和 Linux/Unix 上的 Apache 服务器,一般都需要进行额外的配置:

  • 对于 Windows 上的 IIS 服务器,可以设置 中配置启用 Gzip 压缩
  • 对于 Linux/Unix 上的 Apache 服务器,请参考本文。可以将下面 2.a、ii 里的代码直接放到 <VirtualHost > 声明里面,当然也可以使用 .htaccess。Apache 的 .conf 配置文件和 .htaccess 中很多东西是一样的。虽然 Apache 的官方网站上有关于 Apache Module mod_deflate的配置,无中文版。
    • Apache 有两种压缩选项:
      • mod_deflate 是标准配置,而且很简单;
      • mod_gzip 功能更加强大:你能够提前压缩这些内容(比如下面提到的 WPSC 就是用这种方式工作的)。

2、没有服务器配置权限

一般的小网站主,特别是个人博客(比如我),使用的是共享空间,很少有服务器的配置权限的。这样还可以分为 2 种情况:

a、服务器开启了 mod_gzip 或者 mod_deflate 模块,但是没有默认支持 Gzip on-the-fly (即时压缩)

这一种情况还好点儿,只需要在 .htaccess 文件中配置使用压缩模块即可:

i、打开 .htaccess 文件。如果你使用共享空间上提供的控制面板(如 Cpanel)里的文件管理器的话,还需要选中“显示隐藏文件”才能看到该文件。使用 ftp 软件(如 FileZilla)管理文件的话也需要类似设置;

ii、在 .htaccess 中靠前的位置添加下面的代码(文件中原有的代码请不要动)

# gzip on js and css
# It will save tons of resources, we promise.
# mod_gzip,使用 Gzip 模块
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl|css\?.*|js\?.*)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
# mod_deflate 使用 deflate 模块
<ifModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/css\?(.*)
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-httpd-eruby
AddOutputFilterByType DEFLATE text/html
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.avi$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mov$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp3$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.mp4$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.rm$ no-gzip dont-vary
</ifModule>

因为不好判断服务器到底开启了哪个压缩模块,所以上面的代码将 2 个模块都包含进去了。但是没有关系,模块开头已经进行了判断,即使服务器没有开启压缩模块也不会有坏的影响。

iii、保存(并上传该文件以替换原文件)

b、服务器没有开启 mod_gzip 或者 mod_deflate 模块

如果是这种情况就比较麻烦了,基本上不可能利用压缩传输的所有优点,不过还是能利用一些的。因为服务器上都必须能够进行压缩文件的处理,尽管不能用来响应浏览器的请求。不过过程就很繁琐了,建议只用其中前两条:

i、如果你是 WordPress 用户,可以安装缓存插件 WP Super Cache (WPSC)并设置开启压缩缓存模式。但是这个只能压缩 HTML 文件,对 XML、CSS 和 JavaScript 等文件却无能为力。

ii、既然有(i)的能力,我们就可以通过 ob_gzhandler 来压缩 CSS

iii、仿照(ii)的方法处理 XML、js(JavaScript)文件。

五、检验压缩效果

一旦你配置好了就可以检查看看效果:

1、在线检查:使用网页gzip压缩检测来做个简单的测试;或者使用 Web Page Test 工具得到比较详细的检测结果(包含 HTML、CSS、JS 等文件是否被压缩传输的详细结果),如下图 4 所示。没有对 JS 文件进行压缩传输,所以即使结合前面 b(i) 和 b(ii) 两种途径也不会达到 100 分,但是 95 分是没问题的。

图4 在线测试结果(A、仅使用方法 b(i);B、仅使用方法 b(ii);C、网页性能指示)

这里分数是不重要的,重要的是传输时间的减少。可惜没有好的方法对时间进行测试所以不能给出具体的结果。

我现在使用的共享空间不支持 Gzip on-the-fly (即时压缩),这也是我要介绍这个东西的动因。在没有使用方法 b(ii) 时,单击测试结果页面右上角的文字压缩等级(如上图 4 中 C 所示,左边起第二个标签),可以看到分析结果如下:

FAILED – (26.1 KB, compressed = 7.0 KB – savings of 19.1 KB) – ………/style.css?v=17

意思是我的 CSS 文件没有进行压缩传输。并说明如果进行压缩传输可以节省 19.1KB 的传输量。按照我的网站的平均访问速度 15KB/s 计算,可节省时间 1 秒多。

2、在浏览器中检测。需要用到 Chrome 或者 Firefox 浏览器。具体就不再详细说明了。可参考https://addons.mozilla.org/en-US/firefox/addon/60

六、一些说明

当然,HTTP 压缩可以带来很多优势,但是也有一些需要注意的地方:

1、老的浏览器:某些老的浏览器可能不支持,比如 IE4 等。Apache 的 mod_deflate 模块有些针对老浏览器的避免规则可以参考。

2、已经压缩的内容:大多数图片、音乐和视频是已经经过压缩的文件,对这些文件不要启用上述功能。你只需要关注“三大件”(HTML, CSS 和 Javascript)。

3、CPU 资源:即时压缩文件虽然能节省带宽却肯定会占用 CPU 时间。通常情况下,压缩过程可以很快完成,所以相比较而言总体上是加快了网页打开速度。而且还有方法可以提前将内容压缩好,但是需要很复杂的配置。

开启压缩功能能够极大地提升网站性能,也是最快最省钱的方法,大家不妨试试看。

本文参考了 http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/ 上的很多内容。©

本文发表于水景一页。永久链接:<http://cnzhx.net/blog/understanding-and-using-gzip-compression/>。转载请保留此信息及相应链接。

2 条关于 “理解和使用服务器的压缩传输功能” 的评论

    • 谢谢夸奖!因为我自己也刚才搞清楚,就写得详细点儿,免得回头自己都不知道自己写得是什么了 :)

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)