小程序优化36计

时间:2022-04-23
本文章向大家介绍小程序优化36计,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

本文偏技术,可能较枯燥,阅读完大概需要 15分钟

微信小程序转眼上线将近一年了,提供了接近原生App的使用体验,加上一年来不断释放新的能力,获得的关注越来越多。笔者参与到了小程序产品相关的研发工作,感觉对于结构较为复杂的小程序,性能问题还是蛮突出的。

性能优化是一个长久的课题,今天总结了一些在研发过程中的优化策略,有代码层面的,也有一些方案策略层面的,其中一些优化方法也适用于app和web,有些则只适用于小程序。今日抛砖引玉,与各位分享小程序性能优化的36计。

瞒天过海

用户对小程序速度的第一感知就是首屏加载速度,所以首屏加载要快,让用户‘误以为’小程序加载很快。

加快首屏加载,我们做了两件事:缓存和预加载。

缓存是将一些不会经常变化的数据到localstorage里,如顶部tab,运营位等,先展示缓存中的数据,等网络请求回来后再渲染最新的数据。而因为这些数据不会经常发生很大的变化,所以重新渲染的过程用户几乎没有感知。

预加载是预加载页面框架结构,这里分几步:

第一步,对于小程序里相对固定(稳定)的页面结构框架(如首页一般是顶部tab,运营位,列表这样的结构),先预留位置。小程序打开后整个框架是直接出来的,再极快地用localstorage里的数据填上,让用户感觉不到有网络请求。

第二步,对网络动态数据的预加载。接口请求应返回图片宽高,让小程序可以预加载好框架,还可以先加载一张模糊的极小的预览图,等大图加载完毕后再渲染大图。

第三步,对用户即将去到的页面数据预加载。比如首页加载完毕后提前后面几个tab的首屏数据;或者对于列表页和详情页中都要显示的公共数据(如标题、描述、图片,基本在详情页的首屏),从列表页传到详情页,用户就有了秒开详情页的感觉。

首屏加载完成后,再将首屏下面的数据异步加载渲染出来,这种预加载首屏数据+异步加载其他数据的渲染方式,给用户一种页面加载很快的感觉。

偷梁换柱

小程序官方提供了很多组件,但有些常用组件不能满足性能要求,页面一些交互又不能发生很大变化,我们只能出一些替代的技术方案实现,达到【偷梁换柱】的目的。

比如 scroll-view组件,scroll-view在页面中消耗较多的页面性能,导致页面在滚动时常出现页面抖动。页面的DOM结构越复杂(建议DOM节点控制在6层、2k-3k个以内),数量越多,浏览列表越长,抖动越明显。

使用 page 的滚动能力替换scroll-view 组件是一个不错的选择。

但使用的过程中发现,page的滚动有一个明显的问题:

1)page滚动是带动画的,当长列表滚到后面时,前面的列表数据有可能会回收。此时再往回滚动的过程中(比如回到顶部),前面的被回收的列表数据未来得及渲染,会导致短暂白屏。

同样,当在同一个页面的tab来回切换时,我们也使用这种【短延时】方案加载另一个tab的数据,做到秒切tab。

2)当页面的弹窗不得不使用scroll-view时,存在划动穿透的问题,也就是弹窗的scroll-view滚动时,底部的页面会跟着滚动。

在弹窗出现时,将page里的元素的position置为fixed或者高度置为少于一屏,使用page暂时不会滚动,可以缓解这一问题。

擒贼擒王

在性能优化方法论中,有几个步骤:

1、预估性能瓶颈

2、监控性能问题

3、使用工具排查问题

4、实施性能解决方案

所谓擒贼擒王,找到性能瓶颈极为重要。解决性能瓶颈后,就解决了用户体验差的大头,其他一些优化,用户感知可能是微乎其微的。

在像资讯、电商类的小程序中,图片可以说是性能优化里的王了。用户在浏览的过程中加载大量的图片,而图片加载时间、消耗流量也是最多的,所以我们很有必要优化图片的加载。

一、从源文件抓起,减少图片的大小

我们应该对不同场景选择最优的压缩率,例如非retina屏、弱网等可以展示相对低清的图片,而现在大多数cdn服务器也支持图片压缩,可以根据图片实际展示的宽高和像素进行压缩。

这里给大家推荐几个图片压缩工具,最右是无损压缩,越往左,压缩损失越大。

源文件的优化主要参与者是设计师,如果可以的话,可以让设计师们适当了解压缩算法的大致原理,做出一张压缩率更高的图片。

源文件压缩的关键是要选择适合的图片格式。目前webp格式的方案在业内已经比较成熟了,得到了很多应用。在需要下载图片的场景,需要做展示与下载的分离,展示时用webp可以提高加载速度和节省流量,但下载时需下载png、jpg等图片格式,不然用户转发给别人的时候,可能无法正常查看webp格式的图片喔。

低复杂度的图片尽量使用iconfont

借尸还魂

小程序是基于webview开发的,一般适用于web的优化都适用于小程序,例如做动画时尽量使用translate 等消耗GPU的图片变换代替改变 top、left等消耗CPU(计算位置)的操作、尽可能减少列表的dom数量和复杂度。

值得一提的是小程序的JS只能通过setData和视图层交互,而性能并不乐观。

像毫秒级setData会导致页面卡顿明显。在改变视图层时,可以使用css animation 的多帧动画来渲染一段时间内的页面展示,避免多次setData,如像毫秒倒计时就可以用9到0多个view的translate来展示。

另外,页面滚动不断触发 setData时,加上时间控制,减少setData次数,渲染延迟会好很多(例如200ms内发生数据变化只按最后一次数据setData)。

釜底抽薪

网络层如果优化得足够好,相当于是从根本上优化了应用的速度。这里提一些我们实践过或即将实践的方法。

一、使用WebSocket长连接

使用WebSocket长连接后,可以减少每次建立https时,多次握手挥手和检验证书的耗时,而且也不用使用繁重的http报文,节省流量减小包体。

二、拆分页面主次请求

拆分页面主次请求要求程序员在充分理解业务的请求下,区分哪些请求是主要的,哪些是次要的,主要请求永远要优先于次要请求发起。

必要的、需要同时展示的请求,可以合并在一起,减少请求次数;非必要或可以异步的,可以拆分多个请求;请求耗时过长或者经常超时,原因可能是包体过大,丢包率高,由于tcp丢包时的重发机制,是很可能造成网络超时的,这样的接口就可能需要拆分了。

最后谈一下缓存。小程序的缓存在整个网络中无处不在,dns缓存、cdn缓存、redis缓存、图片缓存等等,本文前面几乎每一点或多或少提到了缓存的优化的思维。用好缓存,在小程序性能优化上可能事半功倍。