在 Web 性能优化领域,Gzip 统治了二十余年。但随着网页体积的膨胀和移动端网络的普及,Gzip 的压缩率瓶颈日益凸显。
Brotli (br) 由 Google 于 2015 年推出,专为 Web 文本资源设计。相比 Gzip,它在同等压缩级别下能额外减少 15%-25% 的传输体积。这意味着:
然而,与 Gzip 不同,Brotli 并非 Nginx 内置模块。你需要手动编译安装第三方模块 ngx_brotli。这正是许多开发者望而却步的原因。
???? 本文价值:
彻底消除 Brotli 安装的“黑盒恐惧”。从源码编译到动态加载,从基础配置到生产级最佳实践,一篇文章带你走完全部流程!
|
1 |
nginx -V |
记录输出中的 configure arguments,后续重新编译时需要保持完全一致。同时确认 Nginx 版本 ≥ 1.13.7(推荐 1.20+)。
|
1 2 3 4 5 6 7 8 |
# Debian/Ubuntu sudo apt update sudo apt install -y git gcc g++ make cmake \ libpcre3-dev zlib1g-dev libssl-dev libbrotli-dev
# CentOS/RHEL sudo yum groupinstall -y "Development Tools" sudo yum install -y git pcre-devel zlib-devel openssl-devel brotli-devel |
?? 关键点:libbrotli-dev / brotli-devel 是 Brotli 算法的核心库,缺少它编译必定失败。
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| A. 动态模块加载 (推荐) | 已有生产 Nginx,不想中断服务 | 无需替换二进制,随时卸载 | 需 Nginx ≥ 1.9.11 + --with-compat |
| B. 静态编译 | 全新部署或可接受短暂停机 | 性能略优,兼容所有版本 | 需替换 nginx 二进制,风险较高 |
| C. 包管理器安装 | 快速验证/开发环境 | 一条命令搞定 | 版本不可控,生产不推荐 |
|
1 2 3 4 5 |
cd /usr/local/src git clone --depth=1 https://github.com/google/ngx_brotli.git cd ngx_brotli # 更新内置的 brotli 子模块 git submodule update --init --recursive |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 进入你当前 Nginx 源码目录(版本必须与运行中的一致) cd /usr/local/src/nginx-1.24.0
# 使用 nginx -V 输出的原始参数,追加 --add-dynamic-module ./configure \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --modules-path=/usr/lib64/nginx/modules \ --with-http_ssl_module \ --with-http_v2_module \ --with-compat \ # ← 动态模块必须加这个 --add-dynamic-module=/usr/local/src/ngx_brotli
# 仅编译模块,不安装 make modules |
|
1 2 3 4 5 6 7 |
# 复制生成的 .so 文件到模块目录 sudo cp objs/ngx_http_brotli_filter_module.so /usr/lib64/nginx/modules/ sudo cp objs/ngx_http_brotli_static_module.so /usr/lib64/nginx/modules/
# 在 nginx.conf 最顶部添加 echo 'load_module modules/ngx_http_brotli_filter_module.so;' | sudo tee -a /etc/nginx/nginx.conf echo 'load_module modules/ngx_http_brotli_static_module.so;' | sudo tee -a /etc/nginx/nginx.conf |
|
1 2 |
sudo nginx -t # 语法检查 sudo systemctl reload nginx # 平滑重载,零停机 |
如果你正在从零搭建服务器,可以直接将 Brotli 编入 Nginx:
|
1 2 3 4 5 6 7 |
./configure \ --prefix=/etc/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --add-module=/usr/local/src/ngx_brotli
make && sudo make install |
???? 提示:静态编译后无需 load_module 指令,模块自动可用。
安装完成后,在 http 块中添加以下配置:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
http { # ========== Brotli 动态压缩 ========== brotli on; # 主开关 brotli_comp_level 6; # 压缩级别 (0-11),推荐 4-6 brotli_min_length 256; # 最小压缩长度(字节) brotli_buffers 16 8k; # 压缩缓冲区 brotli_types # 需要压缩的 MIME 类型 text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml font/ttf font/otf;
# ========== Brotli 静态预压缩 ========== # 优先查找 .br 文件,避免实时压缩CPU开销 brotli_static on;
# ========== 兼容性保障 ========== # 为不支持 Brotli 的客户端保留 Gzip 兜底 gzip on; gzip_comp_level 6; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; } |
| 参数 | 推荐值 | 说明 |
|---|---|---|
| brotli_comp_level | 4-6 | 实时压缩黄金区间。>6 时 CPU 消耗急剧上升但收益递减;构建时用 11 |
| brotli_min_length | 256 | 小于此值的响应不压缩,避免负收益 |
| brotli_static | on | 配合构建工具生成 .br 文件,实现零 CPU 压缩 |
| brotli_types | 见上方 | 不包含图片/视频/woff2等已压缩格式 |
|
1 2 3 4 |
curl -H "Accept-Encoding: br" -I https://yourdomain.com/app.js
# ? 成功标志: # Content-Encoding: br |
打开 Network 面板 → 点击任意 JS/CSS 请求 → Response Headers 中确认 Content-Encoding: br。
访问 https://tools.keycdn.com/brotli-test 输入域名即可一键检测。
仍有约 3%-5% 的用户代理不支持 Brotli(老旧浏览器、部分企业代理网关)。Brotli 和 Gzip 必须共存,Nginx 会根据 Accept-Encoding 自动选择最优编码。
主流浏览器仅在 HTTPS 连接上发送 Accept-Encoding: br。如果你的站点仍在使用 HTTP,Brotli 永远不会被触发。
对于高频小响应的 JSON API,Brotli 的压缩启动开销可能超过收益。建议通过 location 精细化控制:
|
1 2 3 4 5 6 7 8 9 10 |
# 静态资源:全力压缩 location ~* \.(js|css|html|svg)$ { brotli on; brotli_comp_level 6; }
# API 接口:谨慎评估 location /api/ { brotli off; # 或使用更低级别 brotli_comp_level 2; } |
上线后密切关注 CPU 使用率。如果发现 Brotli 实时压缩导致 CPU 飙升,应立即: