Skip to content

Gzip 与 Brotli 压缩技术简介及策略选择指南

约 1079 字大约 4 分钟

2025-06-26

总结

  • 压缩算法各自特点横向对比适应场景
    • Gzip
    • Brotli
    • zstand
  • 压缩方案:如何配置如何选择
    • 前端预压缩
    • 服务端实时压缩
    • 服务器实时压缩的进阶方案:渐进式压缩。
    • CDN 动态压缩
  • 压缩阈值和等级选择。为什么这么配置?
    • < 10kb:不压缩
    • 10kb - 50kb:压缩、解压缩效率对比传输效率,不明显。
      1. 预压缩:推荐 gzip 5brotli 9,也可以拉最高。
      2. 动态压缩:gzip 5brotli 9
      3. 渐进式压缩:推荐 gzip 5brotli 9,也可以适当调高。
    • > 50kb: 压缩比拉最高 gzip 9brotli 11

一、核心技术对比

特性GzipBrotli
时间1992 年2015 年
开发背景UNIX 工具Google 开发
压缩算法DEFLATE(LZ77+哈夫曼编码)LZ77 变种+二阶上下文建模
压缩率中等(通常 60-80%)高(比 Gzip 高 15-25%)
压缩速度较慢(高级别时明显)
解压速度非常快快(比 Gzip 慢约 10-15%)
CPU 消耗中高(高级别时)
预定义字典包含 Web 常用术语的静态字典
最佳压缩级别6(性价比最高)5-6(生产环境推荐)
浏览器支持所有浏览器现代主流浏览器,不兼容老版本

二、策略选择决策树

是否需要支持IE等老旧浏览器?
├─ 是 → 强制使用Gzip
└─ 否 →
   ├─ 资源类型:
   │  ├─ 静态资源 → 预压缩Brotli(11级)+Gzip(9级)备用
   │  └─ 动态内容 → 实时Brotli(5级)+Gzip(6级)备用
   └─ 服务器性能:
      ├─ 高配服务器 → 可考虑Brotli更高级别
      └─ 低配服务器 → 降低Brotli级别(4级)

三、具体实施策略

1. 静态资源最佳实践

  • 预压缩方案:

    # 构建时生成两种格式
    webpack --config webpack.prod.js
    find ./dist -type f -size +1024b | grep -E '\.(js|css|html|json|svg)$' | xargs -n1 -P4 brotli -k -q 11
    find ./dist -type f -size +1024b | grep -E '\.(js|css|html|json|svg)$' | xargs -n1 -P4 gzip -k -9
  • Nginx 配置:

    location ~* \.(js|css|html|json|svg)$ {
      brotli_static on;  # 优先使用预压缩.br
      gzip_static on;    # 备用.gz
      etag on;
      add_header Vary Accept-Encoding;
    }

2. 动态内容处理方案

  • Node.js 中间件配置:

    const compression = require("compression");
    const express = require("express");
    
    const app = express();
    app.use(
      compression({
        filter: (req, res) => {
          // 不压缩API响应
          if (req.path.startsWith("/api/")) return false;
          return compression.filter(req, res);
        },
        level: 6, // Gzip级别
        brotli: {
          // Brotli配置
          quality: 5,
          params: {
            [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,
          },
        },
      })
    );

3. 混合部署方案

  • 智能内容协商:

    map $http_accept_encoding $compression_type {
      default          "gzip";
      "~*br"           "br";
    }
    
    server {
      listen 80;
      location / {
        # 根据客户端能力选择压缩方式
        if ($compression_type = "br") {
          brotli on;
          brotli_comp_level 5;
        }
        if ($compression_type = "gzip") {
          gzip on;
          gzip_comp_level 6;
        }
        ...
      }
    }

四、性能优化技巧

1. 压缩阈值控制

# 只压缩大于1KB的文件
gzip_min_length 1024;
brotli_min_length 1024;

# 排除已压缩格式
gzip_disable ".*(jpg|png|gif|mp4|woff2)";

2. 类型针对性优化

# HTML使用更高压缩级别
brotli_types text/html brotli_comp_level 8;

# CSS/JS使用最大压缩
brotli_types text/css application/javascript brotli_comp_level 11;

3. 缓存策略优化

HTTP/1.1 200 OK
Content-Encoding: br
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000, immutable

五、监控与异常处理

1. 关键监控指标

# 压缩率监控
原始大小: 1.5MB
Gzip后: 450KB (压缩率70%)
Brotli后: 380KB (压缩率75%)

# 性能影响监控
CPU使用率增加: ~15%
TTFB增加: 2-5ms

2. 故障转移方案

location / {
  # 如果Brotli处理失败,自动回退到Gzip
  brotli on;
  gzip on;
  gzip_fallback on;
}

六、现代架构建议

  1. 边缘计算方案:

    • 在 CDN 边缘节点执行压缩

    • 根据客户端能力返回最优格式

    • 示例配置(Cloudflare Workers):

      addEventListener("fetch", (event) => {
        event.respondWith(handleRequest(event.request));
      });
      
      async function handleRequest(request) {
        const acceptEncoding = request.headers.get("Accept-Encoding") || "";
        const response = await fetch(request);
      
        // 优先返回Brotli
        if (acceptEncoding.includes("br")) {
          const compressed = await response.arrayBuffer();
          return new Response(compressed, {
            headers: {
              "Content-Encoding": "br",
              Vary: "Accept-Encoding",
            },
          });
        }
        // 其他情况...
      }
  2. 渐进式加载优化:

    <!-- 配合压缩的懒加载示例 -->
    <script type="module">
      if (
        "connection" in navigator &&
        navigator.connection.effectiveType === "4g"
      ) {
        import("./heavy-module.br.js");
      } else {
        import("./light-module.br.js");
      }
    </script>

选择压缩策略时,建议通过 A/B 测试确定最适合您业务场景的方案。典型现代 Web 应用推荐组合使用两种压缩方式,既能保证兼容性又能获得最佳压缩效果,通常可节省 40-90%的带宽消耗。

更新日志

2025/8/24 08:17
查看所有更新日志
  • e7112-1