Brotli 是 Google 开源的压缩算法,对 HTML / CSS / JS 的压缩率通常比 gzip
高 15-25%。现代浏览器(Chrome 50+ / Firefox 44+ / Safari 11+)全支持,
所以现在没有理由不开。
需要源里有 libnginx-mod-brotli(Debian 12+ / Ubuntu 22.04+ 已带)。
官方仓库的 nginx 不带,要么从 nginx.org 仓库装 nginx-mod-brotli
要么编译时加 --add-dynamic-module=ngx_brotli。
启用
/etc/nginx/nginx.conf 顶部 events {} 之前加:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
http {} 里:
# Brotli for dynamic responses
brotli on;
brotli_comp_level 5;
brotli_min_length 1024;
brotli_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/xml
application/xml+rss
application/x-font-ttf
application/vnd.ms-fontobject
application/x-web-app-manifest+json
font/opentype
image/svg+xml
image/x-icon
text/css
text/javascript
text/plain
text/x-component
text/xml;
# Pre-compressed .br files (built by your asset pipeline)
brotli_static on;
# gzip still on for legacy clients
gzip on;
gzip_comp_level 5;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
application/xml text/xml application/xml+rss image/svg+xml;
为什么 level 5:测试下来 5 是 CPU / 压缩比的甜点。9 会把 CPU 拉满但压缩
比只多 2-3%。
校验
sudo nginx -t && sudo systemctl reload nginx
# 客户端模拟 Brotli 支持
curl -H 'Accept-Encoding: br' -I https://example.com/main.css
# 看返回头里有 content-encoding: br
完整对比:
echo '--- raw ---'
curl -s -H 'Accept-Encoding: identity' https://example.com/main.css | wc -c
echo '--- gzip ---'
curl -s -H 'Accept-Encoding: gzip' --compressed https://example.com/main.css | wc -c
# wc -c 是解压后的字节,看不出区别。改用 -w 看下载字节:
curl -s -H 'Accept-Encoding: gzip' -o /dev/null -w 'gzip: %{size_download}\n' https://example.com/main.css
curl -s -H 'Accept-Encoding: br' -o /dev/null -w 'br: %{size_download}\n' https://example.com/main.css
Brotli static —— 预压缩资源
构建期生成 .br 文件,nginx 命中后直接发文件,省运行时 CPU:
# 给所有 css/js 生成 .br
find /var/www/static -type f \( -name '*.css' -o -name '*.js' \) -print0 \
| xargs -0 -n 1 -P 4 brotli --keep --best
然后 brotli_static on; 会优先发 foo.css.br。
踩过的坑
- 别忘了 gzip 留着,Bot / 旧浏览器不发
br头时 fallback 用。 - 如果前面有 Cloudflare 等 CDN,它已经做了 Brotli,源站没必要再做。
反而源站 Brotli + CDN gzip 链路上会多两次解压压缩。可以关掉源站的 brotli
只留 brotli_static 节省 CPU。 - 静态预压缩别忘了同步部署:CI 在压缩
app.js后没把app.js.br推到
目录,nginx 走的还是动态压缩,毫无收益。
登录后参与评论。