微信小程序优化

226 阅读6分钟

微信小程序如果想要优化性能,有关键的两点:

1.提高加载性能,

2.提高渲染性能,

一,提高加载性能:

(1)当用户点击小程序后发生了什么?

图中三个状态,分别对应小程序的三个状态:

有三个点的白屏:下载代码包的阶段;

没有三个点的白屏:业务代码注入和渲染阶段;

加载中:业务代码请求数据;

总的来说,小程序呈现到用户前,实际经历了下面两阶段:

运行环境的加载;

下载代码包;

下面具体介绍这两个阶段:

运行环境预加载:这部是微信做的,微信会在用户打开小程序之前就已经准备好环境,用户点击小程序入口后,直接下载小程序的代码包即可;

下载代码包启动小程序:小程序代码包里的代码,不是小程序的源代码,而是编译,压缩,打包之后的代码,

上图左侧“预加载”对应的是运行环境的预加载,右侧的“小程序启动”对应的是下载代码包启动小程序。

小程序提供的运行环境,分逻辑层(appservices)和视图层(webview),逻辑层是执行js的地方,视图层是渲染页面的地方,当小程序的代码包下载完成后,业务代码分别注入逻辑层和视图层;

提升加载性能最关键的一点,就是控制包的大小,这也是微信官方的说法;

控制包的大小:

提升体验最直接的方法是控制包的大小,基本上可以说,1M的代码包,下载耗时1秒左右,

控制包的大小的措施:

(1)压缩代码,清理无用的代码;

(2)图片放在cdn,

(3)采用分包策略:分包预加载,独立分包(版本要求有点高)

除了上面讲的控制包的大小,对异步请求的优化也很重要;

对异步请求的优化:

(1)onload阶段就可以发起请求,不用等ready;

(2)请求结果放在缓存中,下次接着用;
(3)请求中可以先展示骨架图;

(4)先反馈,再请求,比如说,点赞的按钮,可以先改变按钮的样式,再发起异步请求;

二,提升渲染性能:

(1)setData干了啥,

每次调用setData,都是逻辑层向渲染层的一次通信,这个通信不是直接给webview,而是通过走了native层,通讯的开销很大;

渲染层收到通讯后,还需要重新渲染出来,所以,一次setData带来两次开销,通信开销+webview更新的开销。

在数据传输时,逻辑层会执行一次Json.stringfy来去除setData数据中不可传输的部分,之后将数据发送给视图层,同时,逻辑层还会将setData所设置的数据字段与data合并,开发者可以通过this.data读取到变更后的数据,

(2)减少setData的数据量,

如果一个数据不影响渲染层,则不用放在setData里

(3)合并setData的请求,减少通讯次数,

(4)列表的局部更新

在一个列表中,有n条数据,采用上拉加载更多的方式,假如这时候想对其中某一个数据进行点赞操作,还能及时看到点赞的效果:此时,可以用setData全局刷新,点赞完成之后,重新获取数据,再次进行全局重新渲染,这样做的优点是:方便,快捷,缺点是:用户体验及其不好,当用户刷量100多条数据后,重新渲染量大会出现空白期(没有渲染过来)

如果采用布局刷新,将点赞的id传过去,知道点的是那一条数据,重新获取数据,查找相对应id的那条数据的下标(index是不会变的),用setData进行局部刷新,this.setData({
list[index]=newList[index]})

(5)小心后台页面的js:小程序中可能有n个页面,所有这些页面,虽然都拥有自己的webview(渲染层),但是却共享同一个js运行环境,也就是说,当你跳到另外一个页面(假设是b页面),本页面(假设是a页面)的定时器等js操作仍在进行,并且不会被销毁,并且会抢占a页面的资源,所以必须手动销毁这些代码。

(6)小心onPageScroll:pagescroll事件,也是一次通讯,是webview层向js逻辑层的通信,这次通信也是开销较大,如果考虑到这个事件被频繁调用,回调函数如果有复杂的setData的话,性能就会很差。

(7)小心获取节点位置:

在h5环境中,为了实现懒加载,下拉加载,我们不得不去获取节点的位置,为啥说不得不,是因为我们本可以用新的api--intersectionObject去实现(google等主流浏览器已支持),但是微信内置x5浏览器很遗憾不支持。

没想到,在小程序环境中,微信竟然良心发现,支持intersectionObject,因此获取节点,还是尽量用api吧。

(8)尽可能用小程序组件:自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响,比如一些运营活动的定时模块可以单独抽出来,做成一个定时组件,定时组件的更新并不会影响页面上其他元素的更新,各组件也将具有各自独立的逻辑空间,每个组件都分别有自己的独立的数据,setData调用,

优化心得:相比于上面的优化策略,最重要的是找出小程序的瓶颈,在自己的实践中,遇到了下面的问题:

下拉加载更多,特别特别卡,通过列表局部更新的技巧,发现性能改善不大,后来发现,是因为首页需要监听scroll事件,导致scroll事件被频繁的触发,回调函数中有耗时操作,导致onreachBottom事件被阻塞了,也就是说,要等大概1-2秒才会发起下一页的请求,取消scroll事件的监听,原本>4s的加载时间,控制在了1s之内,

一些坑:(1)在微信开发者工具没有办法复现某些性能问题,是因为从逻辑层,到webview的通讯,开发者工具底层是通过onpostMessage,微信ios好像是微信自己实现的桥接,所以强烈建议使用真机进行调试。

(2)微信开发者工具,没有办法在network里面看到图片资源的加载,通过trace面板链接安卓真机也没办法看到,如果想测试懒加载的效果,就比较麻烦,需要通过设置微信开发者工具的代理到127.0.0.1,通过charles可以抓包看到。

一些迷茫:搞微信小程序遇到的这些坑,虽然可以收获慢慢经验,但是这些经验并不算是真正的计算机知识,因为这些知识并不是基于对本质底层的理解,而是依靠经验,而经验是很宽就会过时,可能小程序api来一次大生级,小程序的优化手段马上会换另一种。