Nginx 的 map 指令通过识别客户端软硬件特征生成变量,联动 gzip/brotli 实现静态资源动态压缩降级,全程无需 reload;具体包括 UA 判断低性能设备、Accept-Encoding 判断压缩支持、组合信号触发降级,并在 location 中按路径和文件类型差异化执行压缩策略。

Nginx 的 map 指令本身不执行压缩,但它能根据客户端软硬件特征(如 User-Agent、Accept-Encoding、屏幕尺寸提示等)生成变量,再联动 gzip/brotli 开关、压缩级别或是否跳过压缩,实现运行时动态降级——即对特定静态路径(如 /static/, /assets/),在弱设备、弱网或旧浏览器场景下,主动降低压缩强度甚至关闭压缩,以节省 CPU、提升响应速度。
核心逻辑是:识别 → 分类 → 决策 → 执行,全程无需 reload 配置。
识别客户端软硬件特征并映射降级信号
在 http 块中用 map 提取关键信息,生成布尔或等级型变量:
# 根据 UA 判断老旧/低性能设备(如 Android 4.x、iOS 9 以下、旧版微信内置浏览器)
map $http_user_agent $is_lowend_device {
default 0;
"~*Android.*[1-4]\." 1;
"~*iPhone OS [1-9]\." 1;
"~*MicroMessenger/[6-7]\." 1;
}
# 根据 Accept-Encoding 判断是否支持 brotli;不支持则倾向更轻量的 gzip 或禁用
map $http_accept_encoding $prefer_light_compression {
default 0;
"~*br" 0; # 支持 brotli → 可用高压缩
"~*gzip" 1; # 仅支持 gzip → 限中级压缩
"" 2; # 不声明压缩能力 → 默认禁用压缩(最保守)
}
# 组合信号:任一条件触发即启用降级策略
map "$is_lowend_device:$prefer_light_compression" $should_degrade_compression {
"1:0" 1;
"0:1" 1;
"0:2" 1;
"1:1" 1;
"1:2" 1;
default 0;
}✅ 注意:
map支持嵌套组合(用冒号拼接多个变量),避免多层 if 嵌套;所有匹配在请求解析初期完成,无运行时开销。
对特定静态路径启用差异化压缩控制
只对 /static/、/assets/ 等明确路径生效,避免影响 API 或动态内容:
location ^~ /static/ {
# 静态资源根目录
alias /var/www/static/;
# 动态控制压缩开关(Nginx ≥ 1.19.7 才支持变量赋值给 gzip)
gzip $should_degrade_compression;
# 若降级开启,则调低压缩级别、限制类型、禁用 brotli
if ($should_degrade_compression) {
gzip_comp_level 3; # 从默认 6 降至 3,CPU 减半
gzip_types text/css application/javascript; # 仅压缩关键文本,跳过 svg/json
brotli off; # 明确关闭 brotli(更高 CPU)
add_header X-Compression-Mode "degraded";
}
# 正常情况下的完整压缩支持
if ($should_degrade_compression = 0) {
gzip_comp_level 6;
gzip_types text/css application/javascript application/json image/svg+xml;
brotli on;
brotli_types text/css application/javascript application/json image/svg+xml;
add_header X-Compression-Mode "full";
}
}⚠️ 注意:
if在 location 中安全可用(非 server 根层级),且仅用于简单赋值/开关;gzip $variable是 Nginx 1.19.7+ 引入的特性,替代了旧版需配合gzip off/on的繁琐写法。
补充:对图片等二进制资源直接跳过压缩(强降级)
即使路径匹配 /static/,也应排除 .png, .jpg, .webp 等已压缩格式,避免徒增 CPU:
# 在同一 location 内追加
if ($request_filename ~ "\.(png|jpe?g|gif|webp|woff2|mp4|avi)$") {
gzip off;
brotli off;
add_header X-Compression-Skipped "binary";
}Nginx 会按顺序执行 if,后写的规则可覆盖前序设置,确保图片类绝不被压缩。
验证与观测建议
- 加入响应头
X-Compression-Mode和X-Compression-Skipped,便于前端或日志分析实际生效策略; - 结合
$request_time日志字段,对比降级前后首字节时间(TTFB)和传输耗时,确认 CPU 负载下降是否换来端到端体验提升; - 对
User-Agent分类要定期更新——例如将“鸿蒙 4.0 以下”、“折叠屏早期内核”等新出现的低性能场景纳入$is_lowend_device。
不复杂但容易忽略。


















