一、Gzip压缩是什么?
gzip是GNUzip的缩写,是一种文件的压缩格式(也可以说是若干种文件压缩程序),类似的压缩格式还有compress,deflate等。
web上使用gzip编码格式传输有几个要点:
-
浏览器(所有浏览器都支持)和服务器都需要支持gzip编码
-
采用 LZ77 算法与 Huffman 编码来压缩文件,是一种无损压缩算法
-
压缩比率在3-10倍左右(纯文本),可以大大节省服务器的网络带宽
二、Gzip压缩哪些资源?
Gzip采用的是LZ777算法,而LZ77 算法非常适合于压缩那些包含重复和连续序列的数据,如文本文件。它通过记录重复数据的偏移和长度来减少存储空间,从而实现高效的数据压缩。在实际应用中,LZ77 算法通常与霍夫曼编码结合使用,如在DEFLATE压缩算法中,以进一步提高压缩效率。
所以针对前端资源,主要是压缩html、js、css。
而图片资源的重复率很低,甚至压缩后体积更大,图片资源一般采用另外的压缩工具。
三、Gzip压缩方案
1、前端预生成gz文件
(1) 在vite中使用vite-plugin-compression来实现
javascript
import compressPlugin from "vite-plugin-compression";
export default defineConfig({
plugins: [
compressPlugin({
ext: ".gz",// 生成的压缩包后缀
threshold: 0, // 体积大于threshold才会被压缩
filter: () => true,// 默认压缩.js|mjs|json|css|html后缀文件,设置成true,压缩全部文件
deleteOriginFile: false, // 压缩后是否删除原始文件
algorithm: 'gzip', // 压缩算法
}),
],
});
javascript
配置过滤压缩文件有2种方式
1、正则匹配
import { defineConfig } from 'vite'
import compression from 'vite-plugin-compression'
export default defineConfig({
plugins: [
compression({
// 配置 filter 选项来指定压缩文件类型
filter: /.(js|mjs|json|css|html)$/i})
]
})
2、函数返回
export default defineConfig({
plugins: [
compression({
// 指定需要压缩的文件类型
filter: (file) => {
// 压缩 JavaScript 文件
if (file.endsWith('.js') || file.endsWith('.mjs')) {
return true
}
// 压缩 CSS 文件
if (file.endsWith('.css')) {
return true
}
// 压缩 HTML 文件
if (file.endsWith('.html')) {
return true
}
// 压缩 JSON 文件
if (file.endsWith('.json')) {
return true
}
// 压缩字体文件
if (file.endsWith('.woff') || file.endsWith('.woff2') || file.endsWith('.ttf')) {
return true
}
// 压缩 SVG 文件
if (file.endsWith('.svg')) {
return true
}
// 排除不需要压缩的文件
if (file.includes('node_modules') || file.includes('.map')) {
return false
}
return false
}
})
]
})
// 排除 source map 文件
compression({
filter: (file) => {
if (file.endsWith('.map')) return false
// 排除小文件(小于 1KB)
// 注意:这里需要结合其他逻辑获取文件大小
return /.(js|css|html|json)$/i.test(file)
}
})
在webpack中可以使用compression-webpack-plugin来实现
javascript
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
// ...其他配置
plugins: [
new CompressionPlugin({
// 匹配需要进行Gzip压缩的文件类型
test: /.(js|css|html|svg)$/,
// 只有文件大小大于等于该值时才会生成Gzip文件
threshold: 10240,
}),
],
};
(2) ngxin配置
ini
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass https://gza.xcbd-monitor.com/;
}
#charset koi8-r;
#access_log logs/host.access.log main;
#会优先查找静态gzip资源
gzip_static on;
location / {
root webapps;
index index.html index.htm;
}
}
2、ngxin在线压缩
ngxin在线压缩,如何有gz文件,服务器就会默认返回gz文件,如果没有ngxin就会实在压缩,再返回gz文件。当然ngxin压缩的gz文件会有缓存,所以不用太担心消耗服务器性能。
bash
server {
gzip on; # 开启 GZIP
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss; # 指定需要压缩的 MIME 类型
gzip_proxied any;
gzip_min_length 1024; # 只有超过 1KB 的文件才会被压缩
gzip_static on; # 如果存在 .gz 文件,直接返回而不进行动态压缩
gzip_vary on; # 添加 Vary: Accept-Encoding 响应头
}
四、效果展示
在浏览器中按照之前没有压缩的方式进行访问比如 localhost/dist/index.html ,会发现资源的响应结果里面的Content-Encoding为gzip,说明压缩成功,浏览器便会使用gzip策略解压压缩后的资源。

(1)未压缩

(2)压缩后

(3)注意事项
在vite.config.js中的配置有一个选项是deleteOriginFile,是否删除原文件,可以根据项目的实际情况来决定,一般建议保留原文件,如何服务器找不到gz文件,就会默认访问源文件,返回给浏览器。
五、工作原理

markdown
1. 浏览器请求url,并在请求头中设置属性accept-encoding: gzip。这表明该浏览器是支持gzip,该参数浏览器
在请求资源时会自动带上。
2. 服务器在接收到浏览器发送的请求之后,服务器会返回压缩后的文件,并在响应头包含content-encoding: gzip。
若是没有gzip文件,会返回未压缩的文件。
3. 浏览器接收到服务器的响应之后,根据content-encoding: gzip响应头使用gzip策略解压压缩后的资源,通过
content-type内容类型决定怎么编码读取该文件内容。