Brotli 需先编译集成 ngx_brotli 模块并验证生效,再于 http 块中启用 brotli on 且配 gzip off;需按资源类型分层调参,预压缩文件须权限、MIME、路径严格匹配,并保留 gzip 作为兜底。

Brotli 不是 Nginx 自带功能,直接加 brotli on 会报 unknown directive "brotli" 错误——必须先编译集成模块,再分场景调参,否则所谓“极致压缩”只是空谈。
确认 ngx_brotli 模块是否真被编译进 Nginx
光 clone 了 ngx_brotli 仓库、或宝塔点了“添加模块”,不代表生效。关键只看两个输出:
- 运行
nginx -V 2>&1 | grep with-http_brotli_module,有输出才说明 configure 时已注入该模块 - 执行
nginx -t不报unknown directive "brotli",才算通过基础验证 - OpenResty 用户必须用对应版本的
ngx_brotli分支(比如 OpenResty 1.21.x 对应openresty分支),混用会导致make失败 - 宝塔用户别 patch 已安装的二进制,应走「卸载 → 编译安装 → 添加自定义模块」路径
在 http 块中启用 brotli 并规避 gzip 冲突
brotli on 写在 server 或 location 块里大概率无效,Nginx 会忽略。必须放在 http 块顶层,且显式关掉 gzip:
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
-
brotli on和gzip off必须成对出现,顺序无关,但建议紧挨着写在http开头 -
brotli_static on只查同名.br文件(如app.js.br),不生成也不降级;若要压缩动态 JSON/HTML,得设brotli_static off,并在对应location里再写一遍brotli on - 不要依赖“自动协商”:客户端没发
Accept-Encoding: br,服务端绝不会返回Content-Encoding: br
按资源类型分层设置 brotli_comp_level 和 brotli_min_length
统一设 brotli_comp_level 11 会拖慢 TTFB,尤其在高 QPS 接口上。实测有效策略如下:
- 动态内容(API JSON、模板 HTML):
brotli_comp_level 1–4,压缩耗时降 60%,压缩率仍优于gzip 9 - 前端构建产物(
.js/.css):brotli_comp_level 5–6,兼顾压缩率(~63%)与解压延迟(iOS/Android < 8ms) - 长期不变静态资源(SVG、字体、reset.css):
brotli_comp_level 8–11+brotli_static on,前提是构建阶段已生成.br文件 -
brotli_min_length建议设为1024(1KB),避免小响应(如空 JSON)频繁触发 CPU 压缩
预压缩文件权限和 MIME 类型必须严格匹配
brotli_static on 是静默失败型配置——文件存在但权限不对,或 brotli_types 漏写 MIME,Nginx 就当它不存在,也不 fallback 到 gzip:
- 构建阶段生成
.br文件:Vite 用vite-plugin-compression,Webpack 用compression-webpack-plugin,指定algorithm: 'brotliCompress' -
brotli_types必须与实际.br文件的 MIME 严格一致,例如application/javascript不能写成text/javascript -
.br文件权限需为644,确保 Nginx worker 进程可读;否则日志无提示,请求直接走未压缩路径 - 保留
gzip on作为兜底——即使现代浏览器支持率超 98%,仍有监控工具、内网爬虫依赖 gzip
真正难的不是写几行配置,而是把模块编译、MIME 匹配、预压缩生成、权限控制这四件事串成闭环。漏掉任意一环,“极致压缩”就只剩一个 Content-Encoding: br 的幻觉。

















