性能优化之前端与服务端中的 Gzip 压缩全解析

在前端性能优化中,Gzip 压缩是最常见、最有效的手段之一。它能够在不改变业务逻辑的情况下,大幅减少文件传输体积,从而加快页面加载速度。本文将从原理、构建配置、服务端行为到验证方法等角度,完整讲解 Gzip 的工作机制与实践方式。


一、Gzip 压缩的原理

Gzip 是一种基于 DEFLATE 算法 的无损压缩方式。它通过两步实现压缩效果:

  1. LZ77 重复字符串匹配算法:检测文件中重复的字符串,将重复的内容替换为指针引用。

  2. Huffman 编码:对出现频率较高的字节使用更短的二进制表示,降低总体编码长度。

在前端资源(如 HTML、CSS、JS)中,这种算法尤其有效,因为这些文件中存在大量重复的关键字与结构性文本。压缩率通常可达到 60%~90%

浏览器在收到带有 Content-Encoding: gzip 的响应后,会自动解压,不需要开发者进行任何额外操作。


二、前端打包与服务端 Gzip 的关系

很多前端项目会在构建阶段使用插件(如 compression-webpack-pluginvite-plugin-compression)来生成 .gz 文件。与此同时,服务端(如 Nginx、OSS、CDN)也可以开启动态 Gzip 压缩。

需要注意的是:
两者不会导致重复压缩。

  • 如果服务端检测到请求的资源已经是 .gz 格式 ,会直接返回压缩后的内容,并在响应头中声明 Content-Encoding: gzip

  • 如果资源不是 gzip 文件,且服务端开启了压缩,则会在返回时动态压缩。

因此,无论是在构建阶段生成 .gz 文件,还是依赖服务端的实时压缩,都只会有一次实际的压缩操作。


三、前端开启 Gzip 打包的影响

当在前端打包阶段启用 Gzip 插件时,打包产物会在 dist 目录中多出一份 .gz 文件副本。例如:

复制代码
main.js
main.js.gz

这会导致构建后的目录整体体积变大,但仅是文件数量增加,并不影响浏览器加载。实际线上访问时,服务器只会根据配置选择其中一个返回。

对于需要离线运行或本地预览的项目 (如桌面端应用、离线 Web App),不建议在前端打包时生成 .gz 文件,因为:

  • 离线环境不会自动根据 Accept-Encoding 响应。

  • .gz 文件需要额外的服务端配置才能正确返回。

  • 由于 dist 包多了 .gz 文件,导致安装包体积变大

此类项目更适合直接使用未压缩版本。


四、前端上传到 OSS 后的 Gzip 生效方式

即使前端打包时未生成 .gz 文件,只要在 OSS 或 CDN 层开启了 Gzip 压缩,返回内容依然会被自动压缩。

常见的两种情况:

仅上传普通 JS 文件

  • OSS 在返回时根据浏览器请求头自动压缩。

  • 响应头会带上 Content-Encoding: gzip

上传 JS 与 .gz 文件

  • 可通过 CDN 或 OSS 规则,将 .js 请求映射到 .js.gz 文件。

  • 此时无需再开启动态压缩,直接返回静态 .gz 文件即可。

这两种方式的效果是等价的。


五、如何判断 Gzip 是否生效

判断 Gzip 是否生效,可以从以下三个角度验证:

1. 响应头信息

复制代码
Content-Encoding: gzip

说明服务端返回的内容经过 Gzip 压缩。

  1. 同时通常会有:

    Vary: Accept-Encoding

表示服务器根据浏览器的压缩支持情况选择返回内容。

3. 传输体积

在浏览器的 Network 面板中查看:Size:文件实际大小

对比本地打包生成的 .js 文件大小与浏览器请求返回的体积,一般会发现传输文件小于原始文件。


六、请求头中的 Accept-Encoding

Accept-Encoding 是浏览器在请求中自动添加的字段,用于声明自己支持的压缩算法。常见取值如下:

复制代码
Accept-Encoding: gzip, deflate, br, zstd

其中:

  • gzip:最常用的压缩方式,兼容性最佳。

  • br (Brotli):压缩率更高,但部分旧浏览器不支持。

  • deflate / zstd:在某些特定环境使用较少。

浏览器无需手动配置该字段,它由浏览器内核自动添加。服务器根据此字段返回相应的压缩格式。


七、在 Vite 中开启 Gzip 压缩的配置示例

在 Vite 项目中,可以通过 vite-plugin-compression 插件快速启用构建阶段的 Gzip 压缩:

复制代码
npm install vite-plugin-compression --save-dev

vite.config.ts 中添加:

javascript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import viteCompression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    vue(),
    viteCompression({
      verbose: true,             // 控制台输出压缩结果
      disable: false,            // 启用压缩
      threshold: 10240,          // 只压缩大于 10kb 的文件
      algorithm: 'gzip',         // 使用 gzip 压缩算法
      ext: '.gz',                // 生成的压缩文件后缀
      deleteOriginFile: false,   // 保留源文件
    })
  ]
})

执行 vite build 后,dist 目录中会同时生成原始文件与 .gz 文件:

复制代码
dist/
 ├─ assets/
 │   ├─ main.js
 │   ├─ main.js.gz
 │   ├─ index.css
 │   └─ index.css.gz

这些 .gz 文件可以直接上传至服务器或 OSS,由 CDN 根据浏览器请求头进行匹配返回。


八、服务端开启 Gzip 压缩的方法

不同服务端框架的配置方式略有不同,以下是常见示例:

1. Nginx 配置 Gzip

nginx.conf 或相应的站点配置中添加:

javascript 复制代码
gzip on;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_vary on;
gzip_static on;  # 若存在 .gz 文件则直接使用

说明:

  • gzip on:启用 gzip 压缩;

  • gzip_types:指定哪些类型的文件启用压缩;

  • gzip_static on:若存在预压缩的 .gz 文件则直接返回。

2. Node.js + Express

javascript 复制代码
import express from 'express';
import compression from 'compression';

const app = express();
app.use(compression()); // 自动对响应启用 gzip

app.use(express.static('dist'));
app.listen(3000);

Express 的 compression 中间件会根据请求头自动判断是否返回压缩数据。

3. Koa 框架

javascript 复制代码
import Koa from 'koa';
import compress from 'koa-compress';

const app = new Koa();
app.use(compress());

九、总结

场景 是否需要前端打包 .gz 是否需要服务端配置 是否会重复压缩 说明
前端生成 .gz + OSS 映射 建议 不需要 CDN 直接返回 .gz 文件
.gz 文件 + OSS 自动压缩 需要 动态压缩返回
离线项目 不推荐使用 gzip

Gzip 的核心在于:减小传输体积、提升加载性能

实际生产中,只需确保:

  • 浏览器请求中有 Accept-Encoding

  • 响应头中有 Content-Encoding: gzip

    即表示压缩已经生效。

相关推荐
魔术师卡颂4 小时前
不就写提示词?提示词工程为啥是工程?
前端·人工智能·后端
訾博ZiBo5 小时前
【Vibe Coding】001-前端界面常用布局
前端
IT_陈寒5 小时前
《Redis性能翻倍的7个冷门技巧,90%开发者都不知道!》
前端·人工智能·后端
歪歪1005 小时前
React Native开发Android&IOS流程完整指南
android·开发语言·前端·react native·ios·前端框架
知识分享小能手5 小时前
uni-app 入门学习教程,从入门到精通,uni-app组件 —— 知识点详解与实战案例(4)
前端·javascript·学习·微信小程序·小程序·前端框架·uni-app
ZYMFZ5 小时前
python面向对象
前端·数据库·python
长空任鸟飞_阿康5 小时前
在 Vue 3.5 中优雅地集成 wangEditor,并定制“AI 工具”下拉菜单(总结/润色/翻译)
前端·vue.js·人工智能
lapiii3585 小时前
快速学完React计划(第一天)
前端·react.js·前端框架