nginx 实现 brotli 与 gzip 双协议共存的关键是依 accept-encoding 头智能选优:brotli 优先、gzip 兜底,需确保模块加载、类型不重叠、协商逻辑正确及静态预压缩协同。

在 Nginx 中实现 Brotli 与 Gzip 双协议共存,关键不是“同时压缩”,而是让服务端根据客户端的 Accept-Encoding 请求头智能选择最优编码——Brotli 优先、Gzip 兜底。这需要模块支持、类型匹配、协商逻辑和缓存协同四者到位。
确认 Brotli 模块已正确加载
Nginx 官方不内置 Brotli,必须通过第三方模块 google/ngx_brotli 编译或安装(如 Ubuntu 的 nginx-extras 包):
- 运行
nginx -V 2>&1 | grep -o ngx_brotli,有输出才表示模块就绪 - 若无输出,需重新编译 Nginx 并加入
--add-module=/path/to/ngx_brotli,同时确保系统已安装libbrotli-dev或对应依赖 - 模块加载成功后,
brotli on;才真正生效;否则所有 Brotli 配置被忽略
配置双协议协商逻辑(Brotli 优先 + Gzip 降级)
二者不叠加,Nginx 会依请求头自动选一种。默认行为即 Brotli 优先,只需避免干扰:
- 在
http{}块中启用两者:brotli on;<br>gzip on;
- 显式限定适用类型,避免重叠或误压:
brotli_types text/html text/css application/javascript application/json image/svg+xml;<br>gzip_types text/plain text/xml application/xml+rss;
(注意:不把同一 MIME 类型同时写进两个指令) - 禁用可能破坏协商的指令,如
gzip_disable或强制gzip_vary off;保持gzip_vary on,确保 CDN 能区分不同编码版本
启用静态预压缩提升高并发稳定性
运行时压缩在流量高峰易引发 CPU 抖动。推荐构建阶段生成 .br 和 .gz 文件,Nginx 直接投递:
- 打包工具(如 Vite/Webpack)配置生成
.br和.gz文件,例如 Vite 使用vite-plugin-compression并设algorithm: 'brotliCompress'和'gzip' - Nginx 启用静态文件优先读取:
brotli_static always;<br>gzip_static on;
- 确保文件权限可读、路径一致(如
/static/app.js.br与/static/app.js同级)
验证协商是否按预期工作
别只看响应头,要确认实际生效路径和覆盖率:
- 用 curl 测试协商结果:
curl -H "Accept-Encoding: br,gzip" -I https://yoursite.com/main.css→ 应返回Content-Encoding: brcurl -H "Accept-Encoding: gzip" -I https://yoursite.com/main.css→ 应返回Content-Encoding: gzip - 在 access_log 中加入
$sent_http_content_encoding字段,采样统计高峰期br/gzip/-(未压缩)占比;若-超过 5%,说明有资源被brotli_min_length(建议设为 1000)、brotli_types或路径问题漏掉 - Chrome DevTools Network 面板中检查关键 JS/CSS 是否带
content-encoding: br,且Content-Length明显小于未压缩体积











