微信小程序性能优化方案-让你的小程序如此丝滑
发布时间:2021-09-22 15:35 浏览次数:次
今天给大家推荐的是小程序中的可优化的技巧和其中的细节部分
微信小程序如果想要优化性能,有关键性的两点:
1.提高加载性能
2.提高渲染性能
首先加载性能
首先,当用户点击小程序后发生了什么?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
上图中的三个状态,我们经常遇到,他们分别对应小程序的下面三个状态:
**有三个点的白屏(左侧):**下载代码包的阶段
**没有三个点的白屏(中间):**业务代码注入和渲染的阶段
**加载中(右边):**业务代码中异步请求数据
总的来说,小程序呈现到用户面前,实际上经历了下面两个阶段
1.运行环境的加载
2.下载的代码包
1
2
下面具体介绍这两个阶段:
运行环境预加载
这是微信做得,微信会在用户打开小程序之前就已经准备好环境,用户点击小程序入口后,直接下载小程序的代码包即可。
下载代码包启动小程序
小程序代码包里面的代码,不是小程序的源代码,而是编译、压缩、打包之后的代码包。
下图中,左侧的“预加载”对应的是运行环境的预加载,右侧的“小程序启动”对应的是下载代码包启动小程序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5eMv8gkn-1597145127594)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200811184301122.png)]
小程序提供的是运行环境,分为逻辑层和视图层,逻辑层是执行JavaScript的地方,视图层是渲染页面的地方。当小程序的代码包下载完毕之后,业务代码分别注入逻辑层和渲染层。
提升家在性能的最最最最关键性一点是,控制包的大小,这个也是微信官方的说法。
控制包的大小
提升体验最直接的方法就是控制小程序包的大小,基本上可以说,1M代码包,下载耗时1秒左右
控制包大小的措施
压缩代码,清理无用的代码
图片放在cdn
采用分包策略
分包预加载
独立分包(版本要求有点高)
除了上面讲的控制包的大小,对一步请求的优化也很重要。
对异步请求的优化
onLoad阶段就可以发起请求,不用等drady
请求结果放在缓存中,下次直接使用
请求中可以先展示骨架图
先反馈,再请求。比如说,点赞的按钮,可以先改变按钮的样式,再发起异步的请求
提升渲染性能
setData干了啥
每次调用一次setData,都是逻辑层向渲染层的一次通讯,这个通信还不是直接传给webView,而是通过走了native层,通讯的开销很大
渲染层收到通讯后,还需要重新渲染出来,所以,emmm,一次setData带来两次开销:通信的开销+webView更新的开销
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nxIdQw04-1597145127596)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200811185448583.png)]
在数据传输时,逻辑层会执行一次json.stringify来去除掉setData数据中不可传输的部分,之后讲数据发送给视图层。同时,逻辑层还会将setData所设置的数据字段与data合并,使开发者可以用,this.data读取到变更后的数据
减少setdata的数据量
如果一个数据不能会影响到渲染层,则不用放在setData里面
合并setData的请求,减少通讯的次数
列表的局部更新
在一个列表中,有N条数据,才用上拉加载更多的方式,加入这个时候相对其中某一个数据进行点赞操作,还能及时看到点赞的效果
此时,可以采用setData全局刷新,点赞完成之后,重新获取数据,再次进行全局重新渲染,这样做的优点是:方便,快捷!缺点是:用户体验极其不好,当用户刷量100多条数据后,重新渲染量大会出现在空白期(没有渲染过来)
如果采用布局刷新,讲点赞的ID传过去,知道点的是那一条数据,将点赞的 ID传过去,知道点的是那一条数据。
重新获取数据,查找相对应ID的那条数据的下标(index是不会改变的)用setData进行局部刷新
this.setData({
list[index] = newList[index]
})
1
2
3
小心后台页面的js
小程序中可能有N个页面,所有的这些页面,虽然都拥有自己的webview,但是却共享一个js运行环境,也就是说,当你跳到了另外一个页面,本页面的定时器等js操作仍在继续,并且不会被销毁,还会强占别的页面的资源
在h5的环境中,当我们跳转到其他页面,老页面的js环境会被自动销毁,定时器什么的都会被销毁掉,因此我们不需要关心老页面中,还有那些js代码可能还会执行,但是子啊小程序中,我们必须手动的清理掉这样的代码
1
小心onPageScroll
onPageScroll事件,也是一次通讯,是webView层向js逻辑层的通讯。
这次通讯也是开销较大,如果考虑这个事件被频繁的调用,回调函数如果有复杂的setData的话,性能就会很差了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cE4niQ70-1597145127599)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200811190712760.png)]
小心获取节点的位置
在h5的环境中,为了实现懒加载、下拉加载,我们不得不去获取节点的位置
为啥不得不呢?因为我们本可以用新的API——————intersectionObject去轻松实现(goole等主流浏览器都已经支持了)。但是微信的内置X5浏览器很遗憾的不支持
没想到,在小程序的环境中,微信竟然良心发现,支持intersectionObject API,因此获取节点的信息,尽量还是用这个API吧。
尽可能使用小程序的组件
自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响,比如一些运营活动的定时模块可以单独抽出来,做成一个定时组件,定时组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立数据、setData调用
记录优化后的数据,和优化前进行对比
如果我们记录下没一个页面的优化前后的首屏渲染数据,并且对比,可以很好的分析每一个页面的性能提升有多少,从而判断自己有没有在做无用功
可以先简单的约定一下,首屏渲染时间的含义为;从小程序页面onload时间算起,页面发起异步请求,请求回来后,把数据通过setData渲染到页面后,上述一整个流程所花费的时间
1
但是,一个小程序项目往往会有很多个页面,手动记录每一个小程序的首屏渲染时间,很麻烦。
我们可以改造this.setData
this._startTime = new. data().getTime();
let fn = this.setData;
this,setData = (obj = {},handle = '') => {
let now = new Date().getTime();
//上报渲染所需要的时间
log(now - this._startTime)
fn.apply(this.[obj,handle]);
};
1
2
3
4
5
6
7
8
上面的伪代码改写了this.setData方法,简单的加入了上报时间点逻辑
优化心得
相比于上面的优化策略,最重要的是找出小程序中的性能瓶颈,自己的优化实践中,遇到了下面的问题,
下拉加载更多,特别特别卡,通过列表局部更新的技巧,发现性能改善不大,后来发现,是因为首页需要监听scroll事件,导致scroll事件被频繁的触发,回调函数中耗时操作,导致onreachBottom时间被阻塞了,也就是说,要等大概2~3秒才会发起下一页请求,取消掉scroll事假的监听,原本>4s的加载时间,控制在1s之内
下拉加载更多,特别特别卡,通过列表局部更新的技巧,发现性能改善不大,后来发现,是因为首页需要监听scroll事件,导致scroll事件被频繁的触发,回调函数中耗时操作,导致onreachBottom时间被阻塞了,也就是说,要等大概2~3秒才会发起下一页请求,取消掉scroll事假的监听,原本>4s的加载时间,控制在1s之内
本文来源于网络,若有侵权请联系3449817223#qq.com,将在第一时间删除。