关键词:nginx 配置资源压缩
在 Nginx 中配置 gzip 或 brotli 压缩时,需综合考虑压缩效率、服务器性能开销、客户端兼容性等核心因素;而不建议对所有前端资源开启压缩,本质是避免“无效压缩”(压缩后体积无明显减小)和“反向损耗”(压缩耗时 > 传输耗时)。以下是具体分析:
一、配置 gzip/brotli 需考虑的核心因素
无论是 gzip 还是 brotli(压缩率通常优于 gzip,但需额外模块支持),配置时需围绕“收益最大化、损耗最小化”展开,核心考虑因素如下:
1. 资源类型适配:选择“高压缩收益”的资源
不同资源的压缩潜力差异极大,需优先对文本类资源开启压缩(压缩率高、收益显著),对二进制资源谨慎处理(压缩率低、甚至体积变大)。
| 资源类型 | 压缩收益 | 建议配置 | 原因 |
|---|---|---|---|
| HTML/CSS/JS | 极高 | 强制开启 | 文本内容重复度高,压缩率可达 60%-80%,传输体积大幅减小。 |
| JSON/XML | 极高 | 强制开启 | 结构化文本,压缩率与 JS 接近,尤其适合 API 响应数据。 |
| 图片(PNG/JPG) | 极低 | 禁止开启 | 本身已是压缩格式(PNG 无损压缩、JPG 有损压缩),再压缩体积基本不变,反而增加耗时。 |
| 视频(MP4/WEBM) | 极低 | 禁止开启 | 视频编码已做深度压缩,gzip/brotli 无法进一步减小体积,纯浪费资源。 |
| 字体(WOFF2) | 中 | 可选开启 | WOFF2 本身已内置压缩(基于 brotli),再压缩收益有限;若使用旧字体格式(WOFF/TTF),可开启。 |
| 压缩包(ZIP/RAR) | 极低 | 禁止开启 | 压缩包本身是压缩格式,二次压缩可能导致体积轻微增大。 |
2. 压缩级别:平衡“压缩率”与“服务器耗时”
gzip 和 brotli 均支持多级别压缩(级别越高,压缩率越高,但消耗 CPU 资源越多、压缩耗时越长),需根据服务器性能和业务需求选择:
-
gzip 压缩级别(
gzip_comp_level 1-9):- 级别 1-3:轻量压缩,CPU 消耗低,耗时短,适合高并发场景(如秒杀、峰值流量),压缩率约 40%-50%;
- 级别 4-6:平衡压缩率与性能,默认推荐级别(Nginx 默认是 1,需手动调至 4-6),压缩率约 50%-70%;
- 级别 7-9:高强度压缩,CPU 消耗高,耗时久,仅适合低并发、对带宽敏感的场景(如静态资源 CDN 后台)。
-
brotli 压缩级别(
brotli_comp_level 1-11):
比 gzip 多 2 个级别,压缩率更高(同级别下比 gzip 高 10%-20%),但 CPU 消耗也更高。推荐级别 4-8,避免使用 9-11(耗时显著增加,收益边际递减)。
3. 客户端兼容性:避免“压缩后客户端无法解压”
压缩生效的前提是客户端支持对应压缩算法(通过 HTTP 请求头 Accept-Encoding: gzip, br 告知服务器),需避免对不支持的客户端发送压缩数据:
- gzip 兼容性:几乎所有现代浏览器(IE6+)、客户端均支持,兼容性无压力。
- brotli 兼容性:支持 95% 以上现代浏览器(Chrome 49+、Firefox 44+、Edge 15+),但需注意:
- 仅支持 HTTPS 环境(部分浏览器限制 HTTP 下不使用 brotli);
- 需 Nginx 额外安装
ngx_brotli模块(默认不内置,需编译时添加或通过动态模块加载)。
配置时需通过 gzip_disable/brotli_disable 排除不支持的客户端,例如:
# gzip:排除 IE6 及以下不支持的客户端
gzip_disable "MSIE [1-6]\.";
# brotli:仅对支持的客户端生效(依赖 Accept-Encoding 头)
brotli on;
brotli_types text/html text/css application/javascript application/json;4. 压缩阈值:避免“小文件压缩反而耗时”
对极小文件(如 < 1KB 的 CSS/JS 片段)开启压缩,可能出现“压缩耗时 > 传输耗时”的反向损耗——因为压缩需要 CPU 计算,而小文件即使不压缩,传输耗时也极短。
需通过 gzip_min_length/brotli_min_length 设置“压缩阈值”,仅对超过阈值的文件开启压缩(Nginx 默认 gzip_min_length 20,即 20 字节,建议调整为 1KB 以上):
# 仅对 > 1KB 的文件开启压缩(单位:字节)
gzip_min_length 1024;
brotli_min_length 1024;5. 缓存与预压缩:减少“重复压缩”损耗
Nginx 默认“实时压缩”(每次请求都重新压缩资源),若资源长期不变(如静态 JS/CSS),会导致重复的 CPU 消耗。需通过以下方式优化:
- 开启压缩缓存:通过
gzip_buffers配置内存缓存,减少重复压缩(Nginx 默认开启,建议调整缓存块大小适配资源):# gzip 缓存:4 个 16KB 块(总 64KB),适配中小型文本资源 gzip_buffers 4 16k;
- 预压缩静态资源:提前通过工具(如
gzip命令、brotli命令)生成压缩后的资源文件(如app.js.gz、app.js.br),Nginx 直接返回预压缩文件,避免实时压缩:# 优先返回预压缩的 .gz 文件(若存在) gzip_static on; # 优先返回预压缩的 .br 文件(若存在,需 brotli 模块支持) brotli_static on;
6. 服务器性能:避免“压缩耗尽 CPU 资源”
压缩(尤其是高级别压缩)会消耗 CPU 资源,若服务器 CPU 核心数少(如 1-2 核)或并发量极高(如每秒万级请求),过度压缩可能导致 CPU 使用率飙升,影响其他服务(如动态请求处理)。
需结合服务器配置调整:
- 低配置服务器(1-2 核):使用 gzip 级别 1-3,关闭 brotli;
- 中高配置服务器(4 核以上):使用 gzip 级别 4-6 或 brotli 级别 4-8;
- 可通过
gzip_threads(仅部分 Nginx 版本支持)开启多线程压缩,分摊 CPU 压力:# 开启 2 个线程处理 gzip 压缩 gzip_threads 2;
二、为何不建议对所有前端资源开启压缩?
核心原因是“部分资源压缩无收益,反而增加损耗”,具体可归纳为 3 类:
1. 压缩收益为负:体积不变或增大
- 已压缩的二进制资源(如 PNG/JPG/MP4/ZIP):本身已通过专业算法压缩(如 JPG 的 DCT 变换、MP4 的 H.264 编码),gzip/brotli 无法进一步减小体积,甚至因“压缩头额外开销”导致体积轻微增大(如 10MB 的 MP4 压缩后可能变成 10.01MB)。
2. 性能损耗 > 传输收益
- 极小文件(如 < 1KB 的 CSS 片段、小图标 base64 字符串):压缩耗时(即使 1ms)可能超过“压缩后减少的传输时间”(假设带宽 100Mbps,1KB 传输时间仅 0.08ms),反而拖慢整体响应速度。
3. 客户端兼容性风险
- 若对不支持 brotli 的旧客户端(如 IE11)发送 brotli 压缩数据,客户端无法解压,会直接返回“空白页面”或“乱码”;
- 虽可通过
Accept-Encoding头判断,但配置不当(如遗漏brotli_disable)仍可能出现兼容性问题,而“不压缩所有资源”是更稳妥的规避方式。
三、推荐的 gzip + brotli 配置示例
结合上述因素,以下是兼顾“性能、兼容性、收益”的配置(需确保 Nginx 已安装 brotli 模块):
http {
# -------------------------- gzip 配置 --------------------------
gzip on; # 开启 gzip
gzip_comp_level 5; # 平衡级别(压缩率 ~60%,CPU 消耗适中)
gzip_min_length 1024; # 仅压缩 >1KB 的文件
gzip_buffers 4 16k; # 内存缓存块
gzip_types
text/html text/css application/javascript
application/json application/xml
text/plain text/javascript; # 仅对文本类资源压缩
gzip_disable "MSIE [1-6]\."; # 排除 IE6 及以下
gzip_static on; # 优先使用预压缩的 .gz 文件
gzip_vary on; # 向客户端返回 Vary: Accept-Encoding 头(利于 CDN 缓存)
# -------------------------- brotli 配置 --------------------------
brotli on; # 开启 brotli
brotli_comp_level 6; # 平衡级别(压缩率 ~70%,比 gzip 高 10%)
brotli_min_length 1024; # 同 gzip 阈值
brotli_types
text/html text/css application/javascript
application/json application/xml
text/plain text/javascript; # 仅对文本类资源压缩
brotli_disable "MSIE [1-6]\.|Firefox/[1-43]\."; # 排除不支持的旧浏览器
brotli_static on; # 优先使用预压缩的 .br 文件
brotli_vary on; # 同 gzip_vary
}总结
配置 Nginx 压缩的核心逻辑是“针对性优化”:
- 只对“文本类资源”(HTML/CSS/JS/JSON)开启压缩,对“二进制资源”(图片/视频/压缩包)坚决关闭;
- 选择“平衡的压缩级别”,避免过度消耗 CPU;
- 通过“预压缩”和“缓存”减少实时压缩损耗;
- 兼容旧客户端,避免因压缩导致的访问异常。
这种策略既能最大化压缩带来的“带宽节省、加载加速”收益,又能最小化服务器性能损耗和兼容性风险。