前端性能优化之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内容类型决定怎么编码读取该文件内容。
相关推荐
鱼前带猫刺猬2 小时前
leafer-js实现简单图片裁剪(react)
前端
用户904706683573 小时前
uniapp Vue3版本,用pinia存储持久化插件pinia-plugin-persistedstate对微信小程序的配置
前端·uni-app
文心快码BaiduComate3 小时前
弟弟想看恐龙,用文心快码3.5S快速打造恐龙乐园
前端·后端·程序员
Mintimate3 小时前
Vue项目接口防刷加固:接入腾讯云天御验证码实现人机验证、恶意请求拦截
前端·vue.js·安全
Larry_Yanan3 小时前
QML学习笔记(三十一)QML的Flow定位器
java·前端·javascript·笔记·qt·学习·ui
练习前端两年半3 小时前
🚀 Vue3按钮组件Loading状态最佳实践:优雅的通用解决方案
前端·vue.js·element
1024小神3 小时前
vue3项目使用指令方式修改img标签的src地址
前端
sujiu3 小时前
CommonJS 原理与实现:手写一个极简的模块系统
前端
用户51681661458413 小时前
使用全能电子地图下载器MapTileDownloader 制作瓦片图层详细过程
前端·后端