brotli_static on + 预生成.br文件是高并发下最稳最快方案——不压缩、不判断、不争抢cpu,nginx直接查文件发送,ttfb最低;需预生成所有文本资源.br副本,nginx配置必须启用brotli_static、声明types、关闭gzip,并确保模块加载、路径可读、缓存协同。

直接用 brotli_static on + 预生成 .br 文件,是高并发下最稳、最快的方式——它不压缩、不判断、不争抢 CPU,Nginx 拿到请求就查文件、读取、发出去,首字节延迟(TTFB)压到最低。
必须预生成 .br 文件,且路径严格匹配
构建阶段就要把 HTML、CSS、JS、SVG、JSON 等文本资源,用 brotli 命令或插件生成同名 .br 副本,例如:app.js → app.js.br,style.css → style.css.br。不能只压大文件,也不能漏掉 text/html 类型的首页文件。
- Vite 项目推荐
vite-plugin-compression,设algorithm: 'brotliCompress'、ext: '.br'、threshold: 10240 - Webpack 用
compression-webpack-plugin,同样指定 Brotli 算法和输出后缀 - 纯静态站点可用 CLI 批量处理:
find dist -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" \) -exec brotli {} \;,注意保留原始文件权限与修改时间
Nginx 配置要“精准启用”,不是简单开个开关
brotli_static 是查找机制,不是压缩指令。它依赖三个硬性条件同时满足:
- 在
http{}块中写brotli_static on;或更严格的brotli_static always; - 显式声明支持类型:
brotli_types text/html text/css application/javascript image/svg+xml application/json;——漏掉text/html,首页就完全不走 Brotli - 必须关闭 gzip:
gzip off;,否则现代浏览器可能触发双编码协商逻辑,增加 TTFB
确保模块加载、路径可读、缓存协同
光有配置没用,运行时链路必须打通:
- 验证模块:执行
nginx -V 2>&1 | grep brotli,有输出才算真正加载了ngx_brotli - 检查文件路径:Nginx 的
root或alias必须指向包含.br文件的物理目录,且 Nginx 用户(如 www-data)有读权限 - 搭配强缓存:对带哈希指纹的资源(如
main.a1b2c3.js.br),加Cache-Control: public, max-age=31536000, immutable,让浏览器永久复用,不发起任何验证请求
高并发下别碰动态压缩,除非你真需要
高流量场景下,brotli on(动态实时压缩)会吃 CPU、拖慢响应,尤其在突发请求时容易成为瓶颈。而 brotli_static on 完全规避这个问题——所有压缩工作前移至构建期,运行时零计算开销。
- 如果必须支持无哈希的老资源(如宝塔后台的
/static/app.js),可配合etag on;和Cache-Control: public, max-age=31536000, immutable,靠 ETag 触发协商缓存 - 不要在
location块里重复写brotli_static on,全局配置一次即可;也不要在同一作用域混用brotli_static on和brotli on,行为不可控











