一、前言
最近在做项目的过程中,发现随着项目越来越大。编译之后的包也越来越大。
之后,进入static下的js文件夹。
于是便在网上搜索各种提升页面及接口响应速度快的办法。无奈的是,网上大多都是从别人那里复制粘贴的帖子。最后也只能自己动手搞。
二、compression-webpack-plugin
言归正传。经过查询,发现前端有个库。compression-webpack-plugin
引入方式也很简单
yarn add compression-webpack-plugin --D
需要注意compression-webpack-plugin得和你项目中的webpack匹配,否则会出现问题。
一般对应图是
compression-webpack-plugin是8.x, 则webpack需要5.x
compression-webpack-plugin是7.x, 则webpack需要5.x
compression-webpack-plugin是6.x, 则webpack需要4.x或者5.x
compression-webpack-plugin是5.x, 则webpack需要4.x或者5.x
比如你项目中的webpack是4.x的,那么compression-webpack-plugin只能用5和6的。不能用7和8版本的。
以vue-cli3.x为例。
const CompressionPlugin = require("compression-webpack-plugin");
...其他代码
configureWebpack:{
plugins:[
new CompressionWebpackPlugin({
test: /\.(js|css)?$/i, // 哪些文件要压缩
filename: "[path][base].gz", // 压缩后的文件名
algorithm: "gzip", // 使用gzip压缩
threshold: 10240, //大于 10240字节,既10k时
minRatio: 0.8, //压缩率
deleteOriginalAssets: true, //是否删除原本的js
});
]
}
...其他代码
先来解释下CompressionWebpackPlugin选项中的几个参数的含义。
1、test:是个正则表达式,表示哪些文件需要压缩。这里我们选择以.js和.css结尾的文件。这样的话下面的文件都在范围内。
2、filename:表示压缩之后的文件名,后缀必须为.gz(是gzip的文件格式),path和base表示,会在压缩时,把源文件的名称和路径都携带上。比如
index.9b65b390.js //需要压缩的源文件
index.9b65b390.js.gz //压缩之后的文件。
3、algorithm:压缩方式。
一般可以选择gzip和brotliCompress两种,brotliCompress稍后会说到。
4、threshold:压缩阈值
表示文件的大小超过定义的字节,就会压缩
threshold: 10240表示,超过10240个字节,也就是超过10k是压缩。
5、minRatio这个没试出来怎么个用法,后面补充。
6、deleteOriginalAssets:表示是否删除源文件。
网上百分之90全写的false。
那么咱们假如有两个文件
index.9b65b390.js
index.9b65b390.js.gz
如果deleteOriginalAssets:true,最后只剩余index.9b65b390.js.gz
而如果deleteOriginalAssets为false,那么最终的源文件和gz文件都在。
最后查看dist,发现比我没压缩前的37M都大。达到了41M
那我图啥呢?图37M不够大吗?
所以如果我们想要让dist变小,那就必须选deleteOriginalAssets为true。
但是注意一点,在development模式下,这个要false,不然浏览器会报错,空白页面。
二、nginx
前端打包好gz后,还需要后端进行配置,以nginx为例。
只需要加一行代码即可。
有的朋友会说。"gzip true"也可以呀。
但是gzip是动态压缩,比如你的接口返回大量数据或者返回静态的大js文件。服务器会根绝你gzip_min_length的配置,去实时压缩,然后给你返回。在这个过程中,服务器是要消耗性能和资源的。你压缩的越小。服务器处理的越慢,相应的你http会等待更长。
而gzip_static是指,直接从服务器上去找.gz的文件。如果有直接返回。没有就退而求其次找源文件。这个过程,服务器响应是很快速的。
你也可以都配置上。gzip_static优先于gzip
location / {
root html;
index index.html;
gzip_static on;
}
gzip on;
gzip_min_length 10k;
gzip_comp_level 1;
gzip_types text/plain application/json application/javascript text/css;
gzip_vary on;
打开浏览器我们可以看到content-encoding为gzip,文件大小为4.2M,比我们刚开始没压缩的13M小了太多了。
最后,gz的文件返回后,不需要显式的处理,浏览器会自动解压。
查看浏览器我们发现,Accept-Encoding定义的浏览器可以接受的压缩格式为gzip, deflate, br三种。而服务器返回给我们的格式是 Content-Encoding:gzip,这OK,浏览器可以处理。
你鼠标放到4.2M这个位置上,会有个类似于title的东西,提示只有4.2M是通过网络传输的。但是实际上源文件有13.9M。
三、Brotli
刚才在CompressionWebpackPlugin中说algorithm时,除了gzip,还有个压缩方式,那就是brotli。
它是一种更加高效的压缩方式。而且各大浏览器基本都支持,但是也严格,需要https才可以,http中不支持Brotli,
下面是vue的配置
const CompressionPlugin = require("compression-webpack-plugin");
const zlib = require("zlib");
...其他代码
configureWebpack:{
plugins:[
new CompressionWebpackPlugin({
test: /\.(js|css)?$/i,
filename: "[path][base].br",
algorithm: "brotliCompress",
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: true, //是否删除原本的js
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
},
},
});
]
}
...其他代码
然后设置nginx的配置。
location / {
root html;
index index.html;
brotli_static on;
}
brotli on;
brotli_comp_level 6;
brotli_buffers 16 8k;
brotli_min_length 20;
brotli_types *;
注意下nginx默认没有brotli模块,需要安装,编译下(后端知道怎么弄,前端不用关心)