你以为开了 Brotli,其实没开
很多站点声称启用了 Brotli,实测却只返回 gzip。原因常常不是厂商不支持,而是协商链路上有一环把 br 丢掉了。
5 分钟协议与压缩

要点
压缩是协商出来的,不是配置出来的。只有分别用 br 和 gzip 各请求一次,才能区分「不支持」和「没请求」。
压缩是协商,不是开关
浏览器在 accept-encoding 里列出自己支持的算法,服务端从中挑一个,并在 content-encoding 里回报选了哪个。全过程是每个请求现场协商的。
这带来一个诊断上的陷阱:如果你抓包时客户端只发了 accept-encoding: gzip,那么服务端返回 gzip 完全正确——你测不出它到底支不支持 Brotli。很多「Brotli 没生效」的结论就是这么误判出来的。
正确的测法
发两次请求:一次 accept-encoding: br,一次 accept-encoding: gzip。只有在明确请求 br 却仍拿到 gzip(或不压缩)时,才能判定 Brotli 确实不可用。
常见的丢失环节
- 源站已压好 gzip 交给 CDN,CDN 默认不会解压再用 Brotli 重压;
- 中间的反向代理(Nginx、负载均衡)改写了 accept-encoding;
- 厂商侧只对特定 content-type 开启压缩,JSON 或字体不在白名单里;
- 文件体积低于厂商的压缩阈值(常见为 1KB 以下不压)——这是合理行为,不是故障。
注意最后一条:小文件不压缩是对的。压缩本身有 CPU 成本,几百字节的文件压完可能更大。判断 Brotli 是否生效,要拿一个足够大的文本文件(比如未压缩的 JS)去测。
值得为它折腾吗
对文本资源(HTML、CSS、JS、JSON),Brotli 通常比 gzip 再小 15%–25%。这部分直接体现在两处:用户的下载时间,以及你的分发流量账单。
流量越大越值得。但要注意压缩等级的取舍:Brotli 最高等级(11)的压缩耗时远高于 gzip,适合构建时预压缩静态文件;动态内容一般用中等等级实时压缩。
在你的网站验证
边缘核验分别用 br、gzip、zstd 各协商一次,区分「不支持」与「没请求」