通常来说,微信小程序如果想要优化性能,关键有两方面:
提高加载性能
提高渲染性能
分别为大家介绍一下:
提高加载性能,模拟一个场景,当用户点击小程序后,程序是如何运作的?
上图中的三个状态,我们经常遇到,它们分别对应小程序的下面三个状态:
有三个点的白屏(左侧);下载代码包的阶段没有三个点的白屏(中间); 业务代码注入和渲染的阶段加载中(右边); 业务代码中异步请求数据
总的来说,小程序从点击后到呈现内容给用户面前,实际上经历了两个阶段:
运行环境的加载
下载代码包
下面具体介绍这两个阶段:
运行环境预加载
这步骤是微信提供的,微信会在用户打开小程序之前就已经准备好环境,用户点击小程序入口后,直接下载小程序的代码包即可。
下载代码包启动小程序
小程序代码包里面的代码,不是小程序的源代码,而是编译、压缩、打包之后的代码包。
小程序提供的运行环境,分为逻辑层(AppService)和 视图层(webView),逻辑层是执行javascript的地方,视图层是渲染页面的地方。当小程序的代码包下载完毕后,业务代码分别注入逻辑层和渲染层。
提升加载性能的最最最关键性一点是,控制包的大小,这个也是微信官方的说法。
控制包的大小
提升小程序性能优化体验最直接的方法是控制小程序包的大小。
控制包的大小的措施:
压缩代码,清理无用的代码
图片放在cdn
采用分包策略
分包预加载
独立分包(版本要求有点高)
除了上面讲的控制包的大小,对异步请求的优化也很重要。
对异步请求的优化
onLoad 阶段就可以发起请求,不用等ready
请求结果放在缓存中, 下次接着用
请求中可以先展示骨架图
先反馈,再请求。比如说,点赞的按钮,可以先改变按钮的样式,再 发起异步请求。
提升渲染性能
setData 干了啥
每调用一次setData, 都是逻辑层向渲染层的一次通讯,这个通信还不是直接传给webView, 而是通过走了native层,通讯的开销很大。
渲染层收到通讯后,还需要重新渲染出来,所以,emmm, 一次setData带来两次开销:通信的开销 + webview更新的开销。
在数据传输时,逻辑层会执行一次JSON.stringify来去除掉setData数据中不可传输的部分,之后将数据发送给视图层。同时,逻辑层还会将setData所设置的数据字段与data合并,使开发者可以用this.data读取到变更后的数据。
减少setData的数据量
如果一个数据不会影响渲染层,则不用放在setData里面
合并setData的请求,减少通讯的次数
列表的局部更新
在一个列表中,有n条数据,采用上拉加载更多的方式,假如这个时候想对其中某一个数据进行点赞操作,还能及时看到点赞的效果
此时,可以采用setData全局刷新,点赞完成之后,重新获取数据,再次进行全局重新渲染,这样做的优点是:方便,快捷!缺点是:用户体验极其不好,当用户刷量100多条数据后,重新渲染量大会出现空白期(没有渲染过来)
如果采用布局刷新,将点赞的id传过去,知道点的是那一条数据, 将点赞的id传过去,知道点的是那一条数据。
尽可能使用小程序组件
自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响;比如一些运营活动的定时模块可以单独抽出来,做成一个定时组件,定时组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用
优化心得
相比于上面的优化策略,最重要的是找出小程序中的性能瓶颈。在自己的优化实践中,遇到了下面的问题:
下拉加载更多,特别卡,通过列表局部更新的技巧,发现性能改善不大。
后来发现,是因为首页需要监听scroll事件,导致scroll事件被频繁的触发,回调函数中有耗时操作,导致onreachBottom事件被阻塞了,也就是说,要等大概1~2秒才会去发起下一页的请求。
取消掉scroll事件的监听,原本>4s的加载时间,控制在1s之内。
一些总结
开发微信小程序遇到的这些问题,虽然可以收获到不少经验,但是这些经验并不算是真正的计算机知识,因为这些知识的并不是基于对本质底层的理解,而是依靠经验,而经验可能很快就会过时,可能下一次小程序api来一次大的升级,小程序优化手段马上就会换成另外一种,所以,作为开发人员需要不断地了解行业内的最新状态,扩大自己的知识面。