前端性能优化之Gzip压缩

一、Gzip压缩是什么?

gzip是GNUzip的缩写,是一种文件的压缩格式(也可以说是若干种文件压缩程序),类似的压缩格式还有compress,deflate等。

web上使用gzip编码格式传输有几个要点:

  1. 浏览器(所有浏览器都支持)和服务器都需要支持gzip编码

  2. 采用 LZ77 算法与 Huffman 编码来压缩文件,是一种无损压缩算法

  3. 压缩比率在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内容类型决定怎么编码读取该文件内容。
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端