gzip 压缩实践笔记

概念理解

gzip 压缩:种基于 DEFLATE 算法的文件压缩格式,主要用于压缩文本类资源。Web 服务器和浏览器通过 HTTP 协议协商压缩,服务器在传输前压缩资源,浏览器接收后自动解压。

压缩原理:通过查找重复的字符串并替换为较短的引用,实现数据压缩。对于文本类资源(HTML、CSS、JavaScript),压缩率通常可达 60%-80%。

压缩策略:

  • 运行时压缩:通过 Nginx 等代理服务器在请求时动态压缩,灵活性高但占用服务器 CPU 资源
  • 构建时压缩 :在构建阶段预先生成 .gz 文件,部署时直接使用,减少服务器运行时压缩开销

Nginx 代理压缩配置

Nginx 作为反向代理服务器,可以在运行时动态压缩响应内容。通过 ngx_http_gzip_module 模块实现 gzip 压缩功能。这是最基础的压缩方案,配置简单,适合快速启用。

1. 基础配置

启用 gzip 压缩:

nginx 复制代码
# 启用 gzip 压缩功能
gzip on;

配置压缩文件类型:

nginx 复制代码
# 指定需要压缩的资源类型
gzip_types text/html text/css application/javascript application/json text/xml application/xml text/javascript;
# 说明:
# - text/html:HTML 文件(可默认存在,可以不写)
# - text/css:CSS 文件
# - application/javascript:JavaScript 文件
# - application/json:JSON 数据
# - text/xml、application/xml:XML 文件
# - text/javascript:JavaScript 文件(兼容写法)

设置压缩阈值:

nginx 复制代码
# 设置文件最小压缩阈值
gzip_min_length 1k; # 小于 1KB 的文件不压缩
# 推荐值:1KB 或 2KB
# 原因:过小文件压缩收益小,压缩开销可能大于收益

设置压缩级别:

nginx 复制代码
# 设置压缩级别(1-9)
gzip_comp_level 6; # 推荐设置为 6
# 说明:
# - Level 1-3:压缩速度快,压缩率较低
# - Level 6:平衡选择,压缩率和速度兼顾(推荐)
# - Level 9:压缩率最高,但 CPU 占用显著增加
# - Level 9 相比 Level 6 只有 5%-10% 的提升,但 CPU 开销却变大了

配置 Vary 响应头:

nginx 复制代码
# 在响应头中添加 Vary: Accept-Encoding
gzip_vary on;
# 作用:告诉 CDN/代理缓存服务,响应内容有多个版本
# 根据 Accept-Encoding 请求头来区分缓存版本
# 避免用户电脑不支持压缩时,代理返回错误的缓存版本

2. 完整配置示例

nginx 复制代码
# 启用 gzip 压缩
gzip on;

# 指定需要压缩的资源类型
gzip_types text/html text/css application/javascript application/json text/xml application/xml text/javascript;

# 设置压缩阈值(小于此大小的文件不压缩)
gzip_min_length 1k; # 推荐:1KB 或 2KB

# 设置压缩级别
gzip_comp_level 6; # 推荐:6(平衡压缩率和 CPU 占用)

# 添加 Vary 响应头
gzip_vary on;

# 禁用对 IE6 的压缩(IE6 对压缩支持有问题)
gzip_disable "MSIE [1-6]\.";

3. 运行时压缩的局限性

问题:Nginx 运行时动态压缩会消耗 CPU 资源,对于高并发场景可能成为性能瓶颈。

  • 每次请求都需要实时压缩,CPU 开销持续存在
  • 高并发场景下,压缩操作可能成为性能瓶颈
  • 压缩级别越高,CPU 占用越大,响应时间可能增加

适用场景:

  • 低并发场景,服务器 CPU 资源充足
  • 无法预压缩的场景(如动态生成的接口数据)
  • 快速启用压缩,无需修改构建流程

构建时预压缩优化方案

为了解决 Nginx 运行时压缩的 CPU 开销问题,可以在构建阶段预先生成 .gz 文件,然后通过 Nginx 的 gzip_static 模块直接使用预压缩文件。这样既能享受压缩带来的带宽节省,又能避免运行时压缩的 CPU 开销。

1. Nginx 静态压缩配置(gzip_static)

配置要求:

  • Nginx 需要编译时包含 --with-http_gzip_static_module 模块
  • 部署时需要同时部署原始文件和 .gz 文件

配置示例:

nginx 复制代码
# 启用静态压缩(优先使用预压缩的 .gz 文件)
gzip_static on;
# 说明:
# - 如果请求的文件存在对应的 .gz 文件,直接返回 .gz 文件
# - 如果 .gz 文件不存在,回退到动态压缩(如果 gzip on 已启用)
# - 这样可以减少服务器运行时压缩的 CPU 开销

# 同时保留动态压缩作为兜底
gzip on;

工作流程:

  1. 客户端请求资源(如 app.js)
  2. Nginx 检查是否存在 app.js.gz 文件
  3. 如果存在,直接返回 app.js.gz(无需压缩,节省 CPU)
  4. 如果不存在,检查 gzip on 是否启用
  5. 如果启用,动态压缩 app.js 并返回
  6. 如果未启用,直接返回原始文件

2. 构建工具插件配置

前端构建时压缩是指在项目构建阶段,通过构建工具插件预先生成 gzip 压缩文件。这种方式可以避免服务器运行时压缩的 CPU 开销,提升响应速度。

2.1 compression-webpack-plugin(Webpack 项目)

compression-webpack-plugin 是 Webpack 的压缩插件,适用于使用 Webpack 作为构建工具的项目。

配置示例:

javascript 复制代码
// vue.config.js 或 webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  chainWebpack(config) {
    // 其他配置...
  },
  configureWebpack: config => {
    // 开发环境不配置压缩
    if (process.env.NODE_ENV !== 'production') return;
    
    // 生产环境配置压缩
    return {
      plugins: [
        new CompressionPlugin({
          // 压缩文件命名方式
          // filename: "[path][base].gz", // 默认方式,每个文件生成一个 .gz 文件
          filename: '[path].gz[query]', // 推荐:合并压缩文件,减少文件数量
          
          // 压缩算法
          algorithm: 'gzip', // 官方默认压缩算法
          
          // 匹配需要压缩的文件类型(使用正则表达式)
          test: /\.js$|\.css$|\.html$|\.ttf$|\.eot$|\.woff$/, 
          // 匹配规则:js、css、html 以及字体文件(.ttf、.woff、.eot)
          
          // 压缩阈值:只压缩超过此大小的文件(单位:字节)
          threshold: 1024, // 推荐:1KB,与 Nginx gzip_min_length 对齐
          
          // 最小压缩比率:只有压缩后体积小于原文件 80% 才保留压缩文件
          minRatio: 0.8, // 官方默认值
          
          // 是否删除原始文件
          deleteOriginalAssets: false // 推荐设置为 false,保留源文件作为双重保障
          // 原因:如果访问 .gz 文件失败,还可以访问原始文件
        })
      ]
    };
  }
};
2.2 vite-plugin-compression(Vite 项目)

vite-plugin-compression 是 Vite 的压缩插件,适用于使用 Vite 作为构建工具的项目。

配置示例:

typescript 复制代码
// vite.config.ts
import { defineConfig } from 'vite';
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
  plugins: [
    viteCompression({
      // 压缩算法
      algorithm: 'gzip', // 可选:'gzip' 或 'brotli'
      
      // 生成的文件扩展名
      ext: '.gz', // gzip 使用 .gz,brotli 使用 .br
      
      // 压缩阈值:仅压缩大于此大小的文件(单位:字节)
      threshold: 1024, // 推荐:1KB,与 Nginx gzip_min_length 对齐
      
      // 是否删除原始文件
      deleteOriginFile: false, // 推荐设置为 false,保留源文件
      
      // 压缩级别:1-9,级别越高压缩率越大,但 CPU 占用越多
      compressionOptions: { level: 9 }, // 构建时可以使用最高压缩级别
      
      // 过滤文件类型:使用正则表达式匹配需要压缩的文件
      filter: /.(js|css|json|html)(?.*)?$/i, 
      // 匹配:js、css、json、html 文件
      // 注意:后面 (?.*)?$ 是带查询参数(?v=xxxx)的匹配逻辑
    }),
  ],
});

3. 构建时压缩配置要点

压缩文件范围 :JavaScript(.js)、CSS(.css)、HTML(.html)、字体文件(.ttf、.woff、.eot),图片文件(.jpg、.png、.gif、.webp)可以借助其他插件进行压缩。

压缩级别选择:可以使用较高压缩级别(6-9),因为构建时压缩不影响运行时性能

双重保障 :保留原始文件,避免代理配置问题导致无法访问 .gz 文件时,可以回退访问原始文件

验证 gzip 压缩生效

怎么验证 gzip 生效 :在网络模块中查看请求响应头,如果显示 Content-Encoding: gzip 就是开启压缩了。

验证步骤:

  1. 打开浏览器开发者工具(F12)
  2. 切换到「网络」(Network)标签页
  3. 刷新页面,查看资源请求
  4. 点击某个资源请求,查看「响应头」(Response Headers)
  5. 检查是否存在 Content-Encoding: gzip 响应头

优化效果 :开启前需要传输 2.4 MB 资源,开启后仅传输 151 KB 压缩资源。

其他

推荐压缩阈值:1 KB - 10KB,过小文件压缩收益小,可能压缩后 HTTP 头部和 gzip 开销更大。

接口压缩 :application/json、application/xml 数据都可以设置 gzip 压缩,但是要从 ROI(Return on Investment 投资回报率)的角度考量,只对大数据量接口的 location 设置 gzip on,小数据量和校验接口没必要开启,多考虑传输耗时和压缩开销。

接口压缩配置示例:

nginx 复制代码
# 只对大数据量接口启用压缩
location /api/large-data {
    gzip on;
    gzip_types application/json application/xml;
    gzip_min_length 1k;
    gzip_comp_level 6;
}

总结

核心策略:

  • 基础方案 :通过 Nginx 配置 gzip on 启用运行时压缩,简单快速
  • 优化方案 :使用构建工具插件预生成 .gz 文件,配合 gzip_static on 优先使用预压缩文件,减少 CPU 开销
  • 双重保障:保留原始文件,避免代理配置问题导致访问失败

配置要点:

  • 压缩级别:运行时推荐 Level 6,构建时推荐 Level 9
  • 压缩阈值:推荐 1KB,构建时和 Nginx 阈值应对齐
  • 压缩范围:只压缩文本类资源(HTML、CSS、JavaScript、字体文件)
  • 接口压缩:根据 ROI 考量,只对大数据量接口启用压缩

验证方法:

  • 浏览器开发者工具查看响应头 Content-Encoding: gzip
  • 对比压缩前后的资源传输大小

注意事项:

  • 开发环境不需要启用压缩,避免影响构建速度
  • 保留原始文件作为双重保障,避免访问失败
相关推荐
AKA__Zas44 分钟前
TCP 与 IP 浅显皮毛
服务器·网络·tcp/ip
奕鼎竜瑆8 小时前
Solid 前端响应式开发从零到精通
前端·人工智能
源流之道8 小时前
联想Y700 五代(TB323FU)刷 ColorOS 16 教程指南
网络·ai·刷机指南·刷机心得
GEO从入门到精通8 小时前
课程怎么选?2026年GEO学习资源全梳理
学习
动恰客流统计8 小时前
景区客流统计怎么做?兼顾管控与运营的实施方案解析
大数据·前端·人工智能
优化Henry9 小时前
LTE 载波频率与频点配置详解
运维·网络·学习·5g·信息与通信
派小心.9 小时前
A/B测试工具免费版够用吗?
前端·数据分析
xiaomu001239 小时前
高湿环境床垫湿度管理技术框架:湿度阈值、排湿结构与材料选型
经验分享·学习·学习方法
前端snow9 小时前
ai agent --- redis 缓存
前端
科力锐品牌君9 小时前
应用级灾备 | 海量非结构化数据如何实现高效数据保护
linux·运维·网络·安全·系统安全·数据安全·灾备