gzip 压缩
HTML/CSS/JS 这些文本文件通常很大——一个 React 应用打包后几百 KB 是常事。但它们都是文本,重复内容多,用 gzip 压缩能轻松砍掉 70% 的体积。Nginx 内置 gzip 模块,几行配置就能让页面加载快 2-3 倍,是性价比最高的性能优化。
1. 为什么要压缩?数据对比
下面是常见资源的典型压缩比(生产实测):
| 资源类型 | 原始大小 | gzip 后 | 节省 |
|---|---|---|---|
| HTML 文档 | 50 KB | 12 KB | 76% |
| CSS 文件 | 200 KB | 30 KB | 85% |
| JS(React 等) | 350 KB | 110 KB | 69% |
| JSON API 响应 | 20 KB | 4 KB | 80% |
| SVG 图片 | 80 KB | 18 KB | 78% |
| JPG/PNG/MP4 | 500 KB | 500 KB | 0%(已压缩过) |
结论:文本类资源压缩效果显著,已经压缩过的二进制(图片/视频/字体 woff2)不要再压,反而浪费 CPU。
2. 最基础的 gzip 配置
三行就能跑起来:
# 最基础的 gzip 配置
http {
gzip on; # 开启 gzip
gzip_types text/plain text/css application/json; # 对哪些 MIME 类型压缩
}这个配置会让 Nginx 对 plain/css/json 三种类型的响应启用 gzip 压缩。但生产环境还需调优,下面是完整版。
3. 生产级 gzip 完整配置
# 生产级 gzip 配置(推荐直接复制)
http {
# === 基础开关 ===
gzip on;
gzip_vary on; # 响应头加 Vary: Accept-Encoding(CDN/缓存正确处理)
# === 压缩级别(1-9)===
gzip_comp_level 6; # 6 是性能与压缩比的平衡点(9 几乎不增益但很耗 CPU)
# === 触发压缩的最小文件大小 ===
gzip_min_length 1024; # 小于 1KB 不压缩(压缩增益抵不过头开销)
# === 压缩缓冲区 ===
gzip_buffers 16 8k; # 16 个 8KB 缓冲区(共 128KB)
# === HTTP 版本 ===
gzip_http_version 1.1; # 对 HTTP/1.1 及以上启用(默认 1.1)
# === 待压缩的 MIME 类型 ===
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/x-javascript
application/json
application/xml
application/xml+rss
application/xhtml+xml
application/atom_xml
application/rss+xml
image/svg+xml # SVG 也是文本,可压缩
font/woff2
font/ttf;
# 注意:text/html 永远会被压缩(不用显式列出)
# 不要压缩 jpg/png/gif/mp4/zip 这些已经压缩过的二进制文件
}几个关键参数详解:
- gzip_comp_level:1 最快、9 最小。实测 6 之后增益急剧减小,CPU 开销却线性上升,推荐 5-6。
- gzip_min_length:小于这个值的响应不压缩——压缩本身有头开销,太小的文件压缩后可能反而更大。
- gzip_types:只压缩文本类型,不要压缩 jpg/png/mp4/woff2(已压缩过,浪费 CPU)。
- gzip_vary on:响应头加
Vary: Accept-Encoding,让 CDN 知道"压缩和未压缩是不同响应",避免给老浏览器发 gzip。
4. 反向代理场景的 gzip
当 Nginx 作为反向代理时,后端(Node.js/Python)可能已经压缩过响应,也可能没压缩。用 gzip_proxied 控制:
# 当 Nginx 作为反向代理时,后端可能压缩过响应,
# proxy 的 gzip 行为需要单独配置
server {
location /api/ {
proxy_pass http://backend;
# 让 Nginx 压缩后端返回的未压缩响应
gzip_proxied any; # 对所有代理请求启用压缩
# 可选值组合(按需选):
# off 完全不压缩代理响应(默认)
# expired 如果响应头有 Expires,且已过期
# no-cache 响应头有 Cache-Control: no-cache
# no-store 响应头有 Cache-Control: no-store
# private 响应头有 Cache-Control: private
# no_last_modified 响应没有 Last-Modified
# any 任何情况都压缩(最激进)
}
}常见错误:后端和 Nginx 都开 gzip——后端压缩完发给 Nginx,Nginx 又解压再压缩,浪费 CPU。建议后端关掉压缩,统一让 Nginx 处理。
5. Brotli:比 gzip 更先进
Brotli 是 Google 推出的新一代压缩算法,比 gzip 多压 15-25%,所有现代浏览器都支持:
# Brotli 是 Google 推出的新一代压缩算法
# 比 gzip 多压缩 15-25%(尤其对文本/JS),但需要额外模块
# Ubuntu/Debian 安装 brotli 模块
sudo apt install -y libnginx-mod-http-brotli-filter
# 配置
http {
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml;
# gzip 和 brotli 可以同时开
# Nginx 会根据客户端 Accept-Encoding 自动选择
# 现代浏览器都支持 br,老浏览器回退到 gzip
}
# 验证是否启用了 brotli
curl -H "Accept-Encoding: br" -I https://example.com/
# 响应头 Content-Encoding: br 表示启用了 brotliBrotli 需要 Nginx 编译或安装 brotli 模块(Ubuntu 包名 libnginx-mod-http-brotli-filter),不是默认就有。但装上后效果立竿见影,强烈推荐。
6. 验证压缩是否生效
配置完一定要验证,不要假设生效。用 curl 检查:
# 验证 gzip 是否生效
curl -H "Accept-Encoding: gzip" -I http://example.com/
# 关键响应头:
# Content-Encoding: gzip 表示已压缩
# Vary: Accept-Encoding 表示按 Accept-Encoding 区分响应
# Content-Length: 1234 压缩后的字节数
# 实际对比压缩前后大小
curl -s http://example.com/ | wc -c # 不压缩
curl -s -H "Accept-Encoding: gzip" http://example.com/ | wc -c # 压缩后
# 浏览器 DevTools → Network → 看 Size 列:
# 比如一个 200KB 的 JS 文件,gzip 后只有 60KB(节省 70%)如果响应头里看不到 Content-Encoding: gzip,可能是:
- MIME 类型没列在
gzip_types里——检查后端的 Content-Type。 - 文件小于
gzip_min_length。 - 请求头没有
Accept-Encoding: gzip(很少见,现代浏览器都发)。 - 配置改了但忘记
nginx -s reload。
7. 不能压缩什么?注意事项
- 已压缩的二进制:jpg/png/gif/mp4/zip/woff2——压缩没效果,浪费 CPU。
- HTTPS 流量:完全没问题,gzip 与 HTTPS 兼容。
- 大文件下载:比如几个 GB 的安装包,压缩会撑爆 Nginx 进程内存,应该用
gzip_max_length限制。 - 老 IE:IE6 对 gzip 支持有 bug,但现在没人用了。
- 实时流(SSE/WebSocket):不要压缩,会破坏协议。
8. 完整的"性能优先"gzip 模板
把上面的最佳实践整合起来,下面这个配置可以直接拷贝到生产环境:
- gzip 开启 + comp_level 6 + min_length 1KB;
- 覆盖所有常见文本类型;
- 开启 gzip_vary;
- 反向代理时 gzip_proxied any;
- 有条件就装 brotli,与 gzip 并存。
配合下一章的缓存策略,你的站点性能能秒杀 80% 的网站。
小结
gzip 是 Nginx 性能优化里最简单也最有效的一招——配置一次,永久受益。这一章你学会了完整的 gzip 配置、参数调优、代理场景、brotli 升级、验证方法。下一篇我们讲 Nginx 的日志系统,让站点透明可见。
← 上一篇 HTTPS 与 SSL
下一篇 日志系统 →