关键是由源站统一压缩并预生成.br/.gz文件,CDN仅缓存分发;禁用运行时压缩以避免SRI校验失败;HTTPS是Brotli生效前提。

关键不是“要不要压”,而是“谁来压、什么时候压、压几次”。重复压缩不仅浪费CPU,还会让CDN或浏览器缓存失效,甚至导致校验失败。
明确压缩责任边界,避免源站与CDN双压
如果源站已返回 Content-Encoding: br 或 gzip,主流CDN(Cloudflare、阿里云DCDN、腾讯云CDN)默认不再二次压缩。但若配置错误——比如CDN开启了自动Gzip且源站也开了Brotli,就可能出现:
- 源站返回 .js.br → CDN误判为未压缩,再套一层 gzip → 响应体损坏
- CDN缓存了 br 版本,又因 Vary 头缺失,把同一URL的 gzip 版也缓存成同一key → 混淆返回
解决办法:统一由源站负责压缩,CDN仅做缓存分发。在CDN控制台关闭“自动压缩”功能,并确认源站响应头中包含 Vary: Accept-Encoding(Nginx 中用 gzip_vary on 和 brotli_static always 自动触发)。
静态文件优先预生成 .br/.gz,禁用运行时实时压缩
对 JS/CSS 等构建产物,运行时压缩(尤其是 Brotli 级别 7+)会明显拖慢 TTFB,还可能因并发请求抬高 CPU 使用率。更稳的做法是:
- 构建后立即生成
main.js.br和main.js.gz两个版本 - Nginx 配置
brotli_static always和gzip_static on,优先查磁盘上的预压缩文件 - 删掉
brotli on+gzip on的实时压缩指令(除非需支持动态生成内容)
这样既规避了运行时开销,又确保每个编码格式都有对应缓存副本。
校验逻辑与压缩必须互斥
若前端加载 JS 前校验其 SHA256 值(例如通过 Subresource Integrity),而服务端又启用了动态压缩,会导致解压后内容与哈希不匹配,脚本被浏览器拒绝执行。
正确做法:
- 所有带 SRI 的资源,一律禁用运行时压缩,只提供预压缩的 .br/.gz 文件
- 构建阶段同时生成原始文件、.br、.gz 和对应 integrity 值,写入 HTML 或清单中
- 确认 Nginx 的
location块未对这些路径启用brotli on或gzip on
注意 HTTPS 是 Brotli 的前提条件
浏览器仅在 HTTPS 请求中发送 Accept-Encoding: br。HTTP 环境下会退化为 gzip 或不压缩,此时若源站仍强制返回 br 编码,将导致解析失败。
验证方式:
- 用 curl -I -H "Accept-Encoding: br" https://yoursite.com/main.js 查看是否返回
Content-Encoding: br - 同样测试 HTTP 地址,确认返回的是
gzip或无编码 - Nginx 不需额外判断协议,只要开启
brotli on且客户端声明支持,HTTPS 下自然生效










