SEO 百科

Gzip

本页目录

Gzip

Gzip 是一种文本压缩格式,服务器发送前把文件压小,浏览器收到后解回原样,用 Content-Encoding: gzip 标明压过[2]。它基于 Deflate 算法,这种编码用得最广[4]。它只对文本有效,图片和视频已经压过,再压一遍没有收益。

编码的协商

浏览器在请求里带 Accept-Encoding,写明自己解得了哪些编码;服务器选中一种,用 Content-Encoding 回给浏览器[2]。

GET /app.js HTTP/1.1
Host: example.com
Accept-Encoding: gzip, deflate, br

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: gzip
Vary: Accept-Encoding

阿里云写出这一功能的判定条件:客户端用 Accept-Encoding: gzip 提出请求,服务端回 Content-Encoding: gzip 才算压成功,并说明 Gzip 压缩兼容所有浏览器[5]。

适用与不适用的资源

能压的是文本。这一类文件里重复的标签和空格多,算法找得到规律,HTML、CSS 与 JavaScript 都在其中。阿里云把可压的对象写成一组媒体类型,text/css 与 application/json 在清单上[5],image/svg+xml 也在。NGINX 默认只压 text/html。其余类型要自己列进 gzip_types[1]。

不该压的是压过的格式。阿里云说明 PNG、JPG 这类图片和 MP4 这类视频开 Gzip 无效[5]。MDN 也提醒,对压过的格式再压一层并不合适,结果可能反而变大[2]。体积还有一道窗口:源站文件在 1 KB 到 10 MB 之间才压,两端不压[5]。NGINX 一侧的下限由 gzip_min_length 决定,官方默认是 20 字节[1],比它更短的响应压不出收益,压缩本身要花的时间抵不过省下的几个字节。

gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_vary on;

示例把下限抬到 1 KB,把要压的类型列全,并让响应带上 Vary: Accept-Encoding[1]。gzip 和 gzip_vary 都取 on 或 off,后者默认关闭[1]。

压缩级别的取舍

级别写在 gzip_comp_level 里,取值范围是 1 到 9,官方默认是 1[1]。往上走体积更小,耗时也更长:Google 说明以更高级别压缩文件换取更高压缩比需要更长时间,用户要等资源压缩完毕才拿到响应[4]。两个时机的选择因此不同。

  • 动态压缩:请求到达时才压。省掉构建步骤,适合每次生成的 HTML;级别一高,这段等待就压在访客的响应时间里[4]。
  • 静态压缩:构建时压好存成文件,例如 main.bundle.js.gz,请求来了直接送这一份[4]。级别的耗时挪到了构建阶段,代价是每次构建都要压一遍,级别高时构建时间明显变长。

走静态这一条要准备两件事:送 .gz 文件时把 Content-Encoding: gzip 一起写上,客户端不支持 gzip 时得能送回原始文件[4]。

与 CDN 配合的冲突

两头都开压不出更小的体积。阿里云写明,源站开启了压缩功能、响应里携带了 Content-Encoding,节点侧的压缩功能将不再生效[5]。问题在于看不出这份内容是谁压的,排查要顺着响应头逐层比对。

共享缓存这一侧还有副本归属的问题。缓存本来按网址分键,Vary: Accept-Encoding 让它改按网址与请求标头来分键,压过的与没压的各存一份[3]。NGINX 用 gzip_vary 决定响应里带不带这个标头,官方默认是 off[1]。少了它,节点会把压好的副本发给解不开的一方,页面直接白屏。

附录

参见

参考资料

官方(境外)

  1. 《Module ngx_http_gzip_module》,NGINX。
  2. 《Content-Encoding》,MDN Web 文档,2025-07-04 更新。
  3. 《HTTP 缓存》,MDN Web 文档。
  4. 《使用 gzip 压缩网络载荷》,web.dev。

官方(国内)

  1. 《Gzip压缩》,阿里云。

外部链接

无。