HTTP 输出 Gzip 的注意事项
昨天上 Jobsdigg.com 发现 Firebug 里飘红,于是做了一些测试,在这里做个笔记。
如今海量存储已经不是问题,反而是带宽资源有限,成了 Web 应用中主要瓶颈的所在。因此减少响应的传输量也就成了优化的关键。
Yahoo 的 34 条前端优化规则 中提到了 Gzip 压缩,Google 的前端性能最佳实践 中也提到了 Gzip 压缩。把服务器响应中的文本内容用 Gzip 压缩后可以减少大约 70% 的大小。这着实对前端性能和用户体验的提升有明显的帮助。
从 HTTP/1.1 开始,客户端就可以在请求头中添加
Accept-Encoding: gzip,deflate
来向请求的服务器表明自己支持 Gzip 压缩的响应。Web 服务器则在响应头中添加
Content-Encoding: gzip
来向客户端表明响应体是经过 gzip 压缩的。
Apache不同版本使用的模块不同,在 Apache1.3 用的是 mod_gzip 模块,而 Apache2.x 用的是 mod_deflate 模块。用支持压缩的服务器来配置 Gzip 压缩输出是很方便的,它会自动在响应头中添加 Content-Encoding: gzip。
在服务器不支持对响应做 Gzip 压缩的情况下,我们可以事先用 gzip 命令把静态文件(如 js/css/xml/html 等文本内容)进行压缩。但 Web 服务器不会自动在响应头中添加 Content-Encoding: gzip ,必须手动为压缩过的文件添加这个响应头。如果服务器输出的是经过 Gzip 压缩过的内容而响应头中又没有 Content-Encoding 的声明,大多数浏览器不会正确识别响应体,Google Chrome 是个特例。
gzip 命令产生的文件默认是以 .gz 为后缀名的,比如
~$ gzip jquery.js命令输出的就是 jquery.js.gz 文件。一般情况下,浏览器都是以 MIME 来识别响应类型,而不会以后缀名来识别。所以我们把这些静态文件经过手动的 gzip 压缩,把链接请求改成 .gz 的后缀,只要正确声明了 Content-Encoding 就不会有问题,但 Google Chrome 是个特例。 我做了个测试:
| Firefox 3.0 | IE 6 | Google Chrome 2.0 | |
| 未压缩的 js,后缀名 .js | √ | √ | √ |
| 压缩的 js,后缀名 .js,不加 Content-Encoding 声明 | × | × | √ |
| 压缩的 js,后缀名 .js.gz,不加 Content-Encoding 声明 | × | × | × |
| 压缩的 js,后缀名 .js.gz,加 Content-Encoding 声明 | √ | √ | × |
| 压缩的 js,后缀名 .js,加 Content-Encoding 声明 | √ | √ | √ |
所以最好的办法是用 gzip 压缩,但不添加 .gz 保持原文件的后缀名,正确添加 Content-Encoding 声明。这样可以保证多数浏览器可以正确识别。但也有个缺点,就是维护起来就比较麻烦了。
-EOF-
看来,要实现每个浏览器的兼容,
January 23, 2010 3:15 PM真是个不小的问题.