您的位置:首页 > 运维架构 > 网站架构

构建高性能网站的14条法则:使用Gzip压缩组件

2008-02-25 10:44 567 查看
前端开发工程师能力的好坏直接关系着页面的访问快慢(John:要知道,用极其丑陋的table套table做出的页面比简洁的div与table做出的页面无论是从K字节上,还是载入速度上都是极大的消耗),但另一些如用户的带宽等我们无法控制的因素,也会影响到用户访问您web应用的速度。法则1和法则3介绍了如何通过减少不必要的HTTP请求来提升页面加载时间,法则2介绍了用CDN,可以让我们离用户更近,但我们总不能把所有的HTTP请求都优化掉吧。于是,我们这法则4应潮流而生。

  法则4,是通过减少HTTP响应的数据量来加快响应速度。要知道如果一个HTTP的响应足够少,那传输的时间多快呀,因为从服务器端传送到浏览器端的数据包小了,也少了,岂有不快之理。这对像那些网络不太好的用户可是特有效。这一章节就会展示如何通过gzip去压缩HTTP响应,这是减少数据量最 easy的方法,但有得到就会有付出,gzip也会有一些不好的影响,这个后面介绍。

压缩是如何工作的

  很久以前我们就把文件压缩应用在电子邮件和FTP站点当中。直到HTTP/1.1的规范制定,web客户端才开始通过HTTP请求中的 Accept-Encoding 头信息来来表示其支持压缩。
如果web服务器在请求信息中看到这个头信息,它就可以通过响应的 Content-Encoding头信息来返回服务器可用的压缩方式。
  gzip是目前最流行和高效的压缩方式。它是一个可以自由使用,不受专利权限制的压缩格式,是由GNU项目开发出来并定义在RFC1952规范中。另外还有一种压缩方式是deflate,但它不如Gzip那么常用和高效,其实上,我只发现一家网站在使用deflate:msn.com 。而支持deflate数据压缩的浏览器,也支持Gzip,所以Gzip是非常好的选择。

该压缩什么

  服务器要压缩什么是取决于文件格式。很多网站只压缩HTML文件,其实script和样式表文件的也都值得压缩(事实上,任何文本型的数据都可以压缩,包括XML和JSON数据)。图片和PDF文件的则不必再用gzip压缩,因为它们本身就是压缩格式,再多余的压缩只会浪费CPU资源,也得不到多少的文件压缩量。
 
  gzip压缩需要消耗服务器端的CPU,而客户端也需要执行解压gzip格式的数据。至于是否值得压缩的问题,我觉得任何超过1K或2K的文件都值得压缩。mod_gzip_minimum_file_size 参数就可以配置您想要压缩的文件的大小范围,它的默认值是500 bytes.

  老套路,我又调查了美国10大网站使用gzip的情况如下图。有9家都用gzip压缩他们的HTML文件,7家还用gzip压缩了script和样式表文件,其中有5家是完全压缩了所有的script和样式表。一个网站如果压缩所有的HTML文件,样式表,script文件,甚至可以减少70%的数据量,这是我们下面的段落里会提到的。
节省The Savings

  gzip压缩后,返回的数据量一般会减少70%,如下图所示,显示了scrtip,样式表文件在压缩前和压缩后的数据量的变化,同时也显示了如果用deflate方式来压缩的数据量对比。
  很显然,从上图中就知道我们为什么要选择gzip了。gzip会减少约66%的数据量,而deflate只会减少约60%。

配置 Configuration

  配置gzip的模块要取决于您Apache的版本:Apache 1.3使用的是mod_gzip,而 Apache 2.x 使用 的是mod_deflate。这一段落就会讲解如何配置每个模块。

Apache 1.3: mod_gzip

  Apache1.3的gzip压缩功能是通过 mod_gzip 模块来现实的。mod_gzip 有很多的配置参数,这些在mod_gzip的站点上有说明,在这里我介绍一些最常用的参数。

  mod_gzip_on
    开启mod_gzip.
  mod_gzip_item_include
  mod_gzip_item_exclude
   定义要被gzip压缩或不压缩的文件的类型,MIME类型, user agent, 等等。

  大部分的web服务器都会打开mod_gzip,并把text/html设为默认文件类型。最重要的是您应该为script与样式表文件也打开gzip功能。您可以参考下面对Apache 1.3 的配置:

  mod_gzip_item_include  file    /.js$
  mod_gzip_item_include  mime  ^application/x-javascript$
  mod_gzip_item_include  file    /.css$
  mod_gzip_item_include  mime  ^text/css$

  gzip的命令行程序可以控制压缩的级别以及CPU的使用率,但在mod_gzip中却无法配置这些。有时对数据流的压缩会造成CPU的过分负荷,我们可以选择缓存压缩后的响应数据到磁盘或是内存中,如果要手动实现这一功能就太麻烦了,还好,我们可以通过mod_gzip来自动保存压缩后数据到磁盘上,还可以及时的响应更新。实现这一功能则要配置 mod_gzip_can_negotiate 和 mod_gzip_update_static 参数。

Apache 2.x: mod_deflate

  Apache 2.x 是通过mod_deflate 模块来实现压缩。尽管它的名字是deflate,但实际它是实现的gzip压缩方式(John:怪异吧!)。如果要实现像对script和样式表的压缩这种基本的配置只需要下面这一行就够了:

AddOutputFilterByType DEFLATE text/html text/css application/x-javascript

  与mod_gzip不同,mod_deflate可以通过参数配置来控制压缩级别。要获取更多的信息,可查阅Apache 2.0 mod_deflate的文档。

代理缓存 Proxy Caching

  以上介绍的简单配置对直接访问web服务器的方式来说没有一点问题,web服务器通过请求中的Accept-Encoding头信息来判断客户端是否可以支持压缩的数据,然后把压缩或没压缩的数据再返回给客户端,这些都是通过HTTP的header头信息来实现的。

  但如果用户是通过代理上网的,那用户的请求也都是通过代理服务器中转发送的,这时就比较麻烦了:假如用户发请求给代理服务器时,并表明其不支持gzip,而代理服务器再中转数据时却将已经缓存过的压缩的数据返回给用户,这时就会造成用户看到的是一堆乱码,反之亦然。
  要解决这个问题则要在服务器端加上vary头信息。mod_gzip默认是为所有的响应都增加Vary:Accept Encoding头信息,这样代理服务器就会缓存压缩和未压缩版的数据了。

特殊情况 Edge Cases

  目前90%的浏览器都支持gzip。但还是会有一些特殊情况我们不得不考虑,如在早期的IE版本中,特别是IE5.5和IE6.0 sp1存在一些bug,一种比较安全的做法是用"浏览器白名单(browser whitelist)",让服务器端只针对一部分浏览器发送gzip格式的数据。如下的设置就是只针对IE6~9的版本和Mozila 5~9的版本发送gzip数据。
 
  Apache 1.3使用User-Agent:

   mod_gzip_item_include  reqheader  "User-Agent: MSIE [6-9]"
   mod_gzip_item_include  reqheader  "User-Agent: Mozilla/[5-9]"

Apache 2.x 使用 BrowserMatch :

   BrowserMatch  ^MSIE [6-9] gzip
   BrowserMatch  ^Mozilla/[5-9] gzip

  而针对代理缓存,一种方法是在Vary的头信息中加上User-Agent标识来告诉代理服务器,我们使用了白名单;在mod_gzip模块中,如果它发现配置了白名单,则会自动为Vary加上上User-Agent标识。但是不要指望代理服务器会缓存所有的浏览器白名单的每一个url副本。所以我们不得不采用另一个方法:为返回的响应中加上 Vary : * 或 Cache-Control:private 头信息,以表明完全禁止代理服务器的缓存,不让代理去缓存任何一个组件,让用户通过代理时,都要去请求真正的服务器以获得页面数据,事实上Google和Yahoo!都是使用的这一策略,尽管它会带来更多的流量消耗。

  还有一个特殊情况要指出,就是ETags(我们将会在Chapter 13章节单独提到),默认情况下它都不会被压缩,所以最好的办法就是干脆禁用ETags,这个还是放在Chapter 13章节再详谈吧。


  下面三个链接分别是没有gzip压缩,只压缩了HTML和压缩了全部组件的三个链接页面:
 Nothing Gzipped
  http://stevesouders.com/hpws/nogzip.html
 HTML Gzipped
  http://stevesouders.com/hpws/gzip-html.html
 Everything Gzipped
  http://stevesouders.com/hpws/gzip-all.html
  下图就是三者的具体数据量对比和时间对比:

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/FrankTaylor/archive/2008/12/30/3657367.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: