实战剖析-vue项目首屏加载时长优化

京东云开发者
• 阅读 103

现状分析:

首屏速度是用户体验的最关键一环,而首屏速度最大的决定性因素就是资源的加载速度,资源加载速度等于资源大小 + 网速,老的前端项目随着不断增长,代码可能会变得混乱,冗余难以理解,不断的做加法,久而久之,前端性能上就会受到影响,相信大家在工作当中一定遇到,页面加载时间慢,响应时间长等问题,本文将以具体项目为例(vue 2.51.7 webpack:4.23.1),一点一点分析,通过实战的角度,介绍如何对Vue项目的首屏加载时间进行优化。

首先我们分析一下页面加载时间的构成:

(1)资源加载;

(2)代码执行;

(3)页面绘制;



实战剖析-vue项目首屏加载时长优化



打开chrome开发者模式面板,为了更好的还原用户的使用场景,我在设置-节流配置中添加模拟5G的性能分析选项,对网络状况做最大限度还原,开始录制页面加载过程,

通过性能分析工具,我们就能看到一共有哪些执行,花了多长时间,通过查看网络面板,可以查看到每一个资源的加载时间,脚本执行,页面渲染和绘制时间,可以看出等待加载资源过大,执行脚本时长是占据白屏时间的首要因素。也可利用window.performance,以数据化的形式查看页面的各种时间,甚至可以把这些时间指标通过接口的形式发送给服务端,可以监控我们的项目在用户的终端设备中的表现;

window.onload = function(){
    axios({
        url: "xxx",
        data: window.perfoformace
    })
}



实战剖析-vue项目首屏加载时长优化






问题找到了,就解决它

针对资源加载太慢的问题我先寻找大佬赏赐了一些思路:

1、找到是哪个文件过大导致,是否可以拆包;2、如果不是马上需要的资源,可以异步加载;3、利用tree-shaking,尽量使用按需引入;4、定期实效数据可以缓存在cookies/localstorage中;5、进行gzip压缩;6、利用webpack / vite对代码进行压缩;

作为一只资深笨鸟,对大佬的思路领悟只有一二成,用最笨的方法,一条一条排查😬

为了直观的发现文件打包体积问题,可以查看打包时生成的报告,有两种方式:通过命令行参数的形式生成报告,也通过可视化的 UI 面板直接查看报告, npm run build --report的命令就可以生成报告,如图所示:在加上 --report命令后,可以生成 report.html来帮助分析包的内容,通过 http://127.0.0.1:8888/ 就可以查看打包报告里面的内容了 ,如图所示:



实战剖析-vue项目首屏加载时长优化



通过面板分析,app.js压缩后有960kb,发现nutui占据主包体积过大,pinyin.js文件重复多次引入,lodash需要实现按需引入等问题。。。

一、大文件拆包压缩

  • 首先将索引文件通过cdn的方式引入,避免多模块重复引入问题,其次对nutui模块优化,不是首屏加载必须的模块可以按需引入,有一点我们需要注意在对nuti实现外部引入的时候,需要先对vue进行一个引入,因为如果不先引入vue,他就会在console里面报一个错误,原因与elementUI外部引入问题相同,采用cdn的方式引入后,我发现unpkg cnd负优化压缩比gzip还慢,参考大佬建议后,还是决定使用按需引入方式优化。

  • 其次lodashi默认是全包引入的

//全包引入
import { cloneDeep } from "lodash"; 

//只引入cloneDeep函数
import cloneDeep from "lodash/cloneDeep";

通过--report参数 找到具体引入文件,发现尽管只用到了lodash的一个函数,但打包的体积也有几百k,应该就是整包打的,没有按需打包,按照上述方式修改为按需打包,减少包体积,之后需要在.babelrc里做一些配置,安装 npm install babel-plugin-lodash 插件,设置plugins: ["lodash"]参数,之后打包文件就是按需打包的形式了。

  • 说到神兵利器,不得不推荐 https://tinify.cn/ 图片无损压缩工具,由于平时习惯直接从UI站点下载配图,对图片体积不是很敏感,它可以一次性导入批量无损压缩,一波操作下来,img资源从1.3M变成649K,着实很香。🤓

二、异步引入

目前来说比较新的脚手架版本,它生成的项目里面用到的一种prefetch 加载方案,简单介绍一下这种方案,假设有page1 page2 page3三个页面,1和2是同步加载的,3是异步加载的,那么异步加载的page3就会从app.js中单独拆出来作为一个文件模块,首页马上需要加载的文件都会放到app.js里,vendor.js里面就是page1和page2需要用到第三方库,page3中用到的第三方库就会标记一个perfecth,它都会在首屏打开的时候创建link标签去加载,有这个标记的资源会进入队列等待加载。

Vue 2.5.17 版本本身并不直接支持 prefetch 加载,然而,2.x 版本支持异步组件,这可以在某种程度上实现类似 prefetch 的行为,通过动态导入组件来按需加载。例如,可以使用 webpack 的 require.ensure 语法或者 import() 函数来异步加载组件。

components: {
..//
  InsCalc: () => import('@/components/insCalc/insCalc')
..//
}

三、按需引入

  • 现在的打包工具都有一个神兵利器叫做tree-shaking,可以把我们那些第三方库中只用到了的方法打包进去,但是很多库的老版本是不支持tree-shaking,比如我引入的xlsx的用来渲染excel表格,老的版本0.11.2的版本就不支持,我只使用 XLSX.utils.encode_cell / XLSX.utils.encode_range 的方法,打包的代码在压缩前体积就有七百kb,时间怎么也得延长几毫秒吧,升级到0.18之后就可以支持tree-shaking,一般情况下只要支持 import { utils } from "XLSX",都可以利用tree-shaking实现按需引入,这时候打包体积就变成了90kb了。👋

这一系列优化操作下来,再次通过分析工具,app.js主包文件已经有500kb了,虽然不算小,但也有进步了😝 ,加载时长已经变成了4秒左右了。

四、数据缓存

  • 项目中有通过路由拦截的方式实现对用户授权数据进行分析的逻辑,这会直接导致在微信环境下二次跳转到微信生态获取code,由于网络或设备等因素有的用户可能出现三次刷新的情况
beforeRouteEnter(to, from, next) {
 if (//非微信环境) {
   next();
   return;
 }
 const code = to.query.code;
 if (!code) {
     const redirectUrl = `https://jlkauth.jd.com/view?xxxx`;
     const url = `https://open.weixin.qq.com/connect/oauth2/xxxxxx`;

 } else {
 //then 逻辑后才next() }
 },

这个问题不解决,再多的优化都没有用,二次刷新的问题可能直接逼退一部分用户,于是开始着手改实现方案,第一步通过原生js实现内部依赖的功能(axios,路由取参,环境判断等...),脱离对项目中npm包的依赖,鉴于多个项目都在使用这个功能,采用cdn文件引入的方式,统一管理,项目内采用对构造函数的实例进行传参的方式,在index.html中引入,可以在最早的加载时机触发换code的逻辑,减短白屏等待时间,第二步通过对已授权用户的数据缓存,避免刷新页面请求,最大程度的降低了授权操作带来的耗时影响。



<script src="https://cdn.../js/wxShareTrack.js"></script>
<script>
 const wxTrack = new WxShareTrack();
 const visit = {
     visitTitle: '标题信息',
     visitType: '类型'
};
 wxTrack.wechatTrajectoryReport(visit);
../
</script>
  • 第五点和第六点一般我们不会有什么工作量,利用nginx访问资源的时候,一般都是会开启压缩的,利用webpakc或vite对代码进行压缩,也是我们利用npm打包的时候,自动进行压缩的,可以在chrome的network面板中的Content-Encoding这一栏中看到是否开启gizp压缩。





实战剖析-vue项目首屏加载时长优化



结尾

总的来说,性能优化是一个涵盖多个层面的综合性概念,对于不同业务场景下的前端项目而言,适用的方法也各不相同,上述的各种优化措施,是通过分析实际情况,定位性能瓶颈,并选取的适合的优化策略,感谢阅读😘

点赞
收藏
评论区
推荐文章
凯特林 凯特林
3年前
Vue 项目性能优化—实践指南
Vue项目性能优化—实践指南前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效
Souleigh ✨ Souleigh ✨
3年前
Vue 性能优化
前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效的性能、更好的用户体验。本文是作者通过实际
Chase620 Chase620
3年前
面试官问 Vue 性能优化,我该怎么回答
前言Vue框架通过数据双向绑定和虚拟DOM技术,帮我们处理了前端开发中最脏最累的DOM操作部分,我们不再需要去考虑如何操作DOM以及如何最高效地操作DOM;但Vue项目中仍然存在项目首屏优化、Webpack编译配置优化等问题,所以我们仍然需要去关注Vue项目性能方面的优化,使项目具有更高效的性能、更好的用户体验。本文是作者通过
Easter79 Easter79
2年前
springboot2之优雅处理返回值
前言最近项目组有个老项目要进行前后端分离改造,应前端同学的要求,其后端提供的返回值格式需形如{"status":0,"message":"success","data":{}}方便前端数据处理。要实现前端同学这个需求,其实也挺简单的,
Wesley13 Wesley13
2年前
KO
KOKO是一个基于Webpack开发的快速开始Web开发的脚手架工具,具有以下特性:可以当做一个Webpack配置种子来使用,无需二次配置、开箱即用自动支持多页应用(可选)Vue单文件组件的开发方式资源分块加载,内联和异步加载方式管理,低成本实现首屏优化支
Stella981 Stella981
2年前
Android自动化页面测速在美团的实践
背景随着移动互联网的快速发展,移动应用越来越注重用户体验。美团技术团队在开发过程中也非常注重提升移动应用的整体质量,其中很重要的一项内容就是页面的加载速度。如果发生冷启动时间过长、页面渲染时间过长、网络请求过慢等现象,就会直接影响到用户的体验,所以,如何监控整个项目的加载速度就成为我们部门面临的重要挑战。对于测速这个问题,很多同学首先会想到在页面
Stella981 Stella981
2年前
Facebook 将对 React 的优化实现到了浏览器!
点上方蓝字关注公众号「前端从进阶到入院」精选原创好文、进阶交流群助你进入大厂本文转载自公众号「code秘密花园」想要提高一个网页的加载速度是非常困难的,如果你的网站是在使用JavaScript渲染的内容,你必须要在网页的加载速度和网页的输入响应能力之间作出权衡:一次性执行首屏需要执行的逻辑(负载性能好,输入响应能力差)
Stella981 Stella981
2年前
Prefetch和预加载实践
之前介绍了利用Preload优化首屏关键资源的加载(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzA5NzkwNDk3MQ%3D%3D%26mid%3D2650587940%26idx%3D1%26sn%3D12eb51
Stella981 Stella981
2年前
Chrome 75 将原生支持图片的惰性加载
!(https://oscimg.oschina.net/oscnet/e6f244be9e5b2aadb16d8effa40fc569e28.gif)随着浏览器性能的提升,前端也越来越关注用户体验,而影响用户体验其中一个很重要的指标便是受首屏渲染速度。我们常常会针对样式、脚本、图片、音频、视频等资源做处理,比如针对样式和脚本的压缩合并,
京东云开发者 京东云开发者
4个月前
23年通天塔搭建页前端性能优化阶段分享
前言通天塔搭建页项目是用来搭建各类活动页面,比较老且业务复杂的项目,可优化点还是非常多的。今年侧重对运营页首屏加载的性能优化,在保证系统稳定可控、需求持续迭代前提下,最终提升了58.8%速度。在此非常感谢通天塔产品组、后端组、前端组同学,对项目性能优化大力