写点什么

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

  • 2024-04-22
    北京
  • 本文字数:2966 字

    阅读完需:约 10 分钟

现状分析:

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


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


(1)资源加载;


(2)代码执行;


(3)页面绘制;



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


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


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




问题找到了,就解决它

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


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/ 就可以查看打包报告里面的内容了 ,如图所示:



通过面板分析,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 压缩。


结尾

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

发布于: 刚刚阅读数: 5
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
实战剖析-vue项目首屏加载时长优化_京东科技开发者_InfoQ写作社区