gzip 压缩

HTML/CSS/JS 这些文本文件通常很大——一个 React 应用打包后几百 KB 是常事。但它们都是文本重复内容多,用 gzip 压缩能轻松砍掉 70% 的体积。Nginx 内置 gzip 模块,几行配置就能让页面加载快 2-3 倍,是性价比最高的性能优化。

1. 为什么要压缩?数据对比

下面是常见资源的典型压缩比(生产实测):

资源类型原始大小gzip 后节省
HTML 文档50 KB12 KB76%
CSS 文件200 KB30 KB85%
JS(React 等)350 KB110 KB69%
JSON API 响应20 KB4 KB80%
SVG 图片80 KB18 KB78%
JPG/PNG/MP4500 KB500 KB0%(已压缩过)

结论:文本类资源压缩效果显著,已经压缩过的二进制(图片/视频/字体 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 这些已经压缩过的二进制文件
}

几个关键参数详解:

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 表示启用了 brotli

Brotli 需要 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,可能是:

7. 不能压缩什么?注意事项

8. 完整的"性能优先"gzip 模板

把上面的最佳实践整合起来,下面这个配置可以直接拷贝到生产环境:

配合下一章的缓存策略,你的站点性能能秒杀 80% 的网站。

小结

gzip 是 Nginx 性能优化里最简单也最有效的一招——配置一次,永久受益。这一章你学会了完整的 gzip 配置、参数调优、代理场景、brotli 升级、验证方法。下一篇我们讲 Nginx 的日志系统,让站点透明可见。

← 上一篇 HTTPS 与 SSL

下一篇 日志系统

✈️💬