一 背景
当项目部署在外网时,前端首屏加载的平均时间是10S,通过开发者工具查看加载的包,例如chunk-libs.xxx.js的有2.9MB,因为包太大导致加载慢,严重影响了用户体验。
所以解决思路就有了两个:
- 能不能把包变小,下载就会快一些?
- 有一些js、css不经常变化的文件能不能通过浏览器缓存,通过从本地读取缓存来减少下载的时间?
PS:解决问题的过程中感谢分享文档的小伙伴/博主,以下内容是解决的思路,细节问题有问题的小伙伴们可以私聊或者百度,相关资料也比较容易获取。
优化前:
优化后:
二 解决方案
2.1 拆包
拆包顾名思义就是分析我们打的包对应工程代码的哪一个文件,我们可以通过BundleAnalyzerPlugin插件来分析我们打的包里面有什么,如果发现多余且体积大的文件,就可以删除这些文件来达到减小打包体积的目的。
2.1.1 BundleAnalyzerPlugin安装使用
2.1.2 安装好后,我们可以从报告中看到体积较大的svg文件和js文件,根据项目需要我们对这些文件进行处理。需注意报告中模块颜色只是用于区分不同的模块,无特殊意义。且我们看的报告一定要是项目打包之后生成的报告,而不是开发环境中编译后自动启动生成的报告。
2.1.3 根据报告我的处理方式如下:
①删除不必要文件:bootstrap-icons相关文件。处理原因:图标过大且不会使用
①按需导入组件:UmyUi。处理原因:仅部分页面使用
③第三方库使用cdn引用:vue、vue-router、vuex、axios、element-ui。这些样式都是不经常变化的样式,通过cdn单独引用的好处是,第一次获取后可以缓存在浏览器中,后续可以直接读取浏览器缓存,这样子引用不需要打包,就能减少打包的体积,cdn有免费的也有收费的,自己公司有华为云obs的也可以自己将js文件直接存在华为云上,使用华为云的地址
2.2 压缩包
我们的项目是通过nginx进行部署,nginx有一个gzip压缩功能,简单来说当服务端向我们获取资源是,nginx会先将我们的包压缩后在发送给浏览器,浏览器收到后再自行解压,这样子传输的包小了,下载自然而然的快,但是这样有个弊端,nginx是在动态压缩,这个压缩的过程会占用服务器性能。所以更推荐是我们先自己在打包的时候先压缩成gzip,将gzip文件放到nginx上,那浏览器再请求的时后nginx直接将我们压缩后的包传输过去,就不会nginx就不需要再压缩了就不会消耗服务器性能。
2.2.1 vue项目打包时开启gzip压缩,这样打包就会生成.gzip文件,直接把.gzip文件放到nginx下
2.2.2 nginx配置开启gzip,这个可以参考若依框架手册,直接搜索gzip就行
在http配置中加入如下代码对全局的资源进行压缩,可以减少文件体积和加快网页访问速度
# 开启gzip压缩
gzip on;
# 不压缩临界值,大于1K的才压缩,一般不用改
gzip_min_length 1k;
# 压缩缓冲区
gzip_buffers 16 64K;
# 压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_http_version 1.1;
# 压缩级别,1-10,数字越大压缩的越好,时间也越长
gzip_comp_level 5;
# 进行压缩的文件类型
gzip_types text/plain application/x-javascript text/css application/xml application/javascript;
# 跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding"
gzip_vary on;
# IE6对Gzip不怎么友好,不给它Gzip了
gzip_disable "MSIE [1-6]\.";
上述方案配置后由于Nginx的动态压缩是对每个请求先压缩再输出,这样造成虚拟机浪费了很多CPU。解决这个问题可以利用nginx的http_gzip_static_module模块,主要作用是对于需要压缩的文件,直接读取已经压缩好的文件(文件名为加.gz),而不是动态压缩(消耗性能)。所以采用这个方案需要确保目录文件名有生成.gz(最新版本的配置打包默认都会生成.gz文件
首先需要安装nginx的http_gzip_static_module模块
# 安装模块(如果存在其他模块,用空格分开 --with-xxx --with-xxx,防止覆盖)
./configure --with-http_gzip_static_module
# 编译
make & make install
配置nginx.conf的gzip_static属性
server {
listen 80;
server_name vue.ruoyi.vip;
# 开启解压缩静态文件
gzip_static on;
location / {
root /home/ruoyi/projects/ruoyi-ui;
try_files $uri $uri/ /index.html;
index index.html;
}
}
开启gzip_static后,对于任何文件都会先查找是否有对应的gz文件。重启nginx,使其生效
./nginx -s reload
2.3 开启nginx协商缓存,可以让不经常变动的文件直接在本地请求,不需要每次都重新传输
大白话如下:
浏览器:nginx,我第一次来向你请求资源了~
nginx:好的兄弟,资源给你,你拿走后存一份在你那里
浏览器:nginx,我第二次来向你请求资源了,上次你给我的文件我还有,你有要更新的文件吗,没有我就用原来的文件
nginx:兄弟,我没有要更新的,你继续用上一份吧!我就不传给你了
浏览器:好叻,我那边有,加载很快
----版本更新后----
浏览器:nginx,我又来向你请求资源了,上次你给我的文件我还有,你有要更新的文件吗,没有我就用原来的文件
nginx:兄弟,我这里有更新,你那个不能用了,我传一份最新的给你,你再存起来
浏览器:好叻,你传过来吧!我按最新的加载