关键在于构建预压缩、Nginx直读.br文件、关闭gzip干扰,并精准配置brotli_static always、brotli_types及缓存策略,实现零运行时压缩与浏览器秒解压,移动端建议brotli_comp_level 5和brotli_window 256k。

要在 Nginx 中用 Brotli 实现全站页面极速加载,关键不是“开了 brotli on 就完事”,而是构建时压好、运行时零计算、浏览器秒解压——三者闭环才能把 HTML/CSS/JS/SVG 这类首屏关键资源的传输体积压到最低,同时规避 CPU 开销和首字节延迟。
构建阶段:为每个静态文件生成 .br 副本
预压缩必须在打包环节完成,确保 main.js 旁边有 main.js.br,index.html 旁边有 index.html.br,且 MIME 类型完全匹配。
- Vite 项目推荐用
vite-plugin-compression,设algorithm: 'brotliCompress'、ext: '.br'、threshold: 10240(≥10KB 才压),避免小文件得不偿失 - Webpack 用户可用
compression-webpack-plugin,同样指定algorithm: 'brotliCompress',输出目录中必须同时存在原始文件与 .br 文件 - 纯静态站点可批量处理:
find dist -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.svg" \) -exec brotli {} \;,注意保留权限与时间戳
Nginx 配置:精准启用 brotli_static 并关闭干扰项
brotli_static 不是开关,而是一套查找+回退机制。只开 brotli on 是不够的,必须让 Nginx 直接读 .br 文件返回。
- 在
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有输出才算成功;若无,建议换用tiangolo/nginx-brotli等预编译镜像
协同策略:让 .br 文件真正被长期复用
有了文件和配置,还需确保整个链路无断点,浏览器不重复请求、不验证、不解压失败。
- 静态资源路径要可访问:Nginx 的
root或alias必须指向包含 .br 文件的物理目录,且文件权限允许 Nginx 读取 - 搭配哈希指纹与 immutable 缓存:
Cache-Control: public, max-age=31536000, immutable,对app.abc123.js.br这类带哈希的文件生效,浏览器将永久缓存、不发任何验证请求 - 移动端弱网建议调参:
brotli_comp_level 5(HTML/CSS/JS)、brotli_window 256k(覆盖典型跨帧重复),兼顾压缩率与解压效率
验证是否真正生效
别只看配置有没有报错,要实测响应头和体积变化。
- 用 curl 检查:
curl -H "Accept-Encoding: br" -I https://yoursite.com/app.js,响应头应含Content-Encoding: br,且Content-Length明显小于未压缩版本 - 打开 Chrome DevTools → Network 标签页,刷新页面,筛选
br列,确认 HTML、CSS、JS 全部命中 - 对比开启前后 LCP(最大内容绘制)指标,典型优化可缩短 300–800ms











