精通 Nginx 压缩:Gzip 与 Brotli 提升网站性能
通过对比 Gzip 和 Brotli 算法,掌握 Nginx 内容压缩。学习启用两者的实用配置指令,了解性能权衡,并发现最佳实践,例如使用静态 Brotli 文件来大幅减少带宽使用并加速 Web 服务器上的内容交付。
精通 Nginx 压缩:Gzip 与 Brotli 提升网站性能
Nginx 压缩是一种看似微小,但一旦查看网络面板便会发现其巨大影响的优化。一个 CSS 文件、JavaScript 包、HTML 页面、JSON API 响应或 SVG 文件,在网络上传输时体积可以大大缩小,然后在浏览器中再解压回原始内容。
实际的选择通常不是“永远只用 Gzip 或 Brotli”。大多数生产环境会同时使用两者:Brotli 用于支持它的浏览器,Gzip 作为回退方案,以及构建管道可以预先创建的预压缩静态文件。不过,细节很重要。一个复制粘贴的压缩块可能会浪费 CPU、跳过重要的 MIME 类型,或者因为 Brotli 模块实际上并未安装而静默失败。
理解 Nginx 中的 Web 压缩
压缩的工作原理是查找数据(如 HTML、CSS 或 JavaScript 文件)中的重复模式,并用较短的引用替换它们。这减少了通过网络传输的文件总大小。Nginx 作为中间层,在将数据发送到浏览器之前动态应用所选的压缩算法。
Nginx 通常需要 ngx_http_gzip_module 模块用于 Gzip,以及一个单独的 Brotli 模块用于 Brotli。大多数常见的 Nginx 包都包含 Gzip 支持。Brotli 则更不固定:一些发行版将其打包为动态模块,一些第三方仓库包含它,而一些构建版本则根本没有它。
前提条件
如果你计划使用 Brotli,请确保你的 Nginx 安装支持它。你可以通过运行以下命令来检查 Brotli 是否可用:
nginx -V 2>&1 | grep -i brotli
如果输出提到了 Brotli,请确认它是编译进二进制文件还是作为动态模块加载的。在 Debian 或 Ubuntu 系统上,如果你的包使用动态模块,还要检查 /etc/nginx/modules-enabled/ 下的文件:
ls -l /etc/nginx/modules-enabled/ | grep -i brotli
如果在 nginx -t 期间 Nginx 拒绝 brotli on;,则该模块对该正在运行的 Nginx 二进制文件不可用,即使操作系统在其他地方安装了 Brotli 包。
1. 配置 Gzip 压缩
Gzip 是内容压缩的成熟且广泛支持的标准。它在压缩比和 CPU 开销之间提供了良好的平衡。
在 Nginx 配置中启用 Gzip
Gzip 设置通常放在 Nginx 配置文件(nginx.conf 或包含的配置文件)的 http、server 或 location 块中。
要启用 Gzip 压缩,请使用以下指令:
http {
# 启用 Gzip 压缩
gzip on;
# 设置要压缩的最小响应大小(字节)
# 仅压缩大于 1000 字节的文件
gzip_min_length 1000;
# 压缩级别(1=最快/最低压缩率,9=最慢/最高压缩率)
gzip_comp_level 6;
# 指定要压缩的 MIME 类型
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
# 推荐:发送 Vary: Accept-Encoding 标头,以便代理缓存压缩和未压缩版本
gzip_vary on;
# 推荐:添加 gzip 标头以进行标识
gzip_proxied any;
}
关键 Gzip 指令说明
gzip on;:激活 Gzip 模块。gzip_comp_level:将其设置在 4 到 6 之间通常是性能的最佳点。更高的级别可以节省更多带宽,但会增加服务器上的 CPU 使用率。gzip_types:至关重要的是,你绝不应该压缩已经压缩过的格式,如图像(.jpg、.png、.gif)或视频。
2. 配置 Brotli 压缩
Brotli 是 Google 开发的一种较新的压缩算法。对于文本资源,它通常产生比 Gzip 更小的文件。确切收益取决于内容、压缩级别以及文件是在每次请求时压缩还是在部署期间提前压缩。
在 Nginx 配置中启用 Brotli
Brotli 配置使用类似的指令,但将 gzip 替换为 brotli。
brotli on;
brotli_comp_level 6; # 通常推荐 4 到 8
brotli_static on; # 如果可用,启用提供预压缩的 .br 文件
brotli_types text/plain text/css application/json application/javascript application/x-javascript text/xml;
关于预压缩 (brotli_static) 的重要说明:
Brotli 压缩在每次请求时动态执行可能会非常消耗 CPU。一个常见的做法是使用专用的离线工具(如 brotli 命令行工具)预压缩资源,并将 .br 版本与原始文件一起存储(例如,style.css 和 style.css.br)。
设置 brotli_static on; 告诉 Nginx 检查请求的资源是否存在预压缩的 .br 文件,如果客户端支持 Brotli,则直接提供该文件,完全绕过实时处理。
3. Gzip 与 Brotli:做出正确选择
在 Gzip 和 Brotli 之间做出选择很大程度上取决于客户端支持情况和你的服务器资源。
| 特性 | Gzip | Brotli | 建议 |
|---|---|---|---|
| 压缩率 | 良好 | 通常对文本资源更好 | Brotli 通常胜出 |
| CPU 负载(动态) | 低 | 中到高 | Gzip 更轻量 |
| 客户端支持 | 几乎通用(所有现代浏览器) | 非常高(大多数现代浏览器) | Gzip 对于旧版支持更安全 |
| 预压缩 | 可能,但不太常见 | 强烈推荐 (brotli_static) |
如果可能,使用 Brotli 预压缩 |
混合方法:最佳实践
最健壮的现代配置使用混合设置,优先为现代客户端使用 Brotli,同时提供 Gzip 作为可靠的备选方案。
- 优先使用 Brotli: 首先配置 Brotli,通常使用
brotli_static on;以提高速度。 - 回退到 Gzip: 确保启用 Gzip 并配置为处理不支持 Brotli 的客户端。
Nginx 根据客户端的 Accept-Encoding 标头和构建中启用的模块来选择响应。在正常的浏览器流量中,当客户端声明支持 br 时,Brotli 是首选;对于只请求 gzip 的客户端、工具、代理和旧堆栈,Gzip 仍然有用。
混合配置示例
如果你的 Nginx 版本同时支持这两个模块,你可以同时启用它们。Nginx 根据客户端的请求标头优先选择哪个模块提供内容。
http {
# --- Brotli 配置 ---
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml;
# --- Gzip 配置(回退) ---
gzip on;
gzip_comp_level 5;
gzip_vary on;
gzip_proxied any;
gzip_types
text/plain
text/css
application/javascript
application/json
application/xml
image/svg+xml;
}
性能调优技巧
无论你选择哪种算法,请遵循以下最佳实践以获得最大效果:
1. 验证实际响应
不要因为配置文件中包含 gzip on; 或 brotli on; 就认为压缩正在工作。检查实际响应:
curl -I -H 'Accept-Encoding: br,gzip' https://example.com/app.js
curl -I -H 'Accept-Encoding: gzip' https://example.com/app.js
查找 Content-Encoding: br 或 Content-Encoding: gzip。同时,确保可能被 CDN 或共享代理缓存的响应上保留 Vary: Accept-Encoding 标头,以免压缩和未压缩的版本混淆。
2. 避免过度压缩
除非你的服务器严重未充分利用,否则切勿将 gzip_comp_level 或 brotli_comp_level 设置得太高(例如 9 或 11)。文件大小减少的边际收益很少能证明计算所需的额外 CPU 周期是合理的。
3. 缓存预压缩文件
对于 Brotli,使用 brotli_static on; 并预压缩你的静态资源是最大的性能提升。这将 CPU 负载从请求时间转移到部署时间。
4. 测试你的配置
修改 Nginx 配置后,在重新加载之前始终测试语法:
sudo nginx -t
如果成功,重新加载 Nginx 以应用更改:
sudo systemctl reload nginx
你还可以使用浏览器开发者工具或性能测试服务来确认响应是否以 Content-Encoding: gzip 或 Content-Encoding: br 提供。
实际部署方式
如果网站完全没有压缩,请从 Gzip 开始。它内置于大多数 Nginx 包中,可以让你快速获得基准。然后,在确认模块支持并有办法在部署期间为静态资源生成 .br 文件后,再添加 Brotli。
对于 React、Vue 或静态文档站点,最佳设置通常是为构建的资源提供预压缩的 .br 和 .gz 文件,为 HTML 和 API 响应提供适度的动态压缩,以及一个尊重 Accept-Encoding 的 CDN 配置。对于接近 CPU 限制运行的小型 API,保守的 Gzip 级别可能是更好的第一步。
胜利不仅仅是文件更小。良好的压缩可以保持较低的带宽,帮助较慢的客户端连接,并在不更改应用程序代码的情况下消除不必要的传输时间。主要的纪律是测试标头,避免压缩已经压缩的媒体,并保持压缩级别足够“平淡”,以便你的服务器在流量高峰期间仍能正常运转。