小程序优化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缓存、图片缓存等等,本文前面几乎每一点或多或少提到了缓存的优化的思维。用好缓存,在小程序性能优化上可能事半功倍。

本文来自企鹅号 - 程序员和产品经理媒体

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏狮乐园

高级 Angular 组件模式 (1)

Angular到现在已经到5.x的版本了,对于MVVM框架我首先接触的是angularjs后来又转为react,之后换了工作因项目技术栈的原因又转换到之前的an...

10620
来自专栏杨龙飞前端

vue重构后台管理系统调研

Q4要来了,我来这家公司已经一个季度了,通过对公司前端框架的整体认识,对业务的一些认识,发现,这些东西也都是可以重构,无论是v2,还是v3的代码。

23510
来自专栏DeveWork

解决iOS 版Safari 中浮动(float)导致页面右侧偏移的bug

长时间没写CSS代码就是生疏了啊!昨天在用ipad 调试最新的主题的时候遇到了一个坑,现在写在这里记录下——iOS 版Safari 中浮动(float)导致页面...

21660
来自专栏带你撸出一手好代码

把需求变化带来的代码修改成本降至最低的一种方法

为解决工作中一些繁琐的问题, 写了一个GUI程序, 操作界面是这个样子的 ? 这个程序的实现起来并不是非常的繁琐, 但在界面的交互操作上, 也不仅仅只是展示数据...

35570
来自专栏机器学习算法与Python学习

极力推荐的Chrome插件!

Momentum能给单调的Chorme首页披上一个漂亮的风景照,毕竟谷歌浏览器的页面打开是这样的。

15800
来自专栏求索之路

教你用android玩冲顶大会——实现几个小时的财务自由

最近答题类app比较火,玩了几把之后想到为什么不用技术来查找答案呢?因此搞了一款辅助app,能够帮助大家直接搜索答案.经过两天的开发和三天的测试,终于让我的冲...

33260
来自专栏数据小魔方

think-cell chart系列20——使用建议及附加功能

今天是think-cell chart系列收尾篇——使用建议及附加功能。 由于think-cell chart图表插件是office平台的第三方插件,而且图表...

49740
来自专栏Youngxj

YoungxjTools全新上线

15440
来自专栏iOSDevLog

Unity 3D 开发《王者荣耀》:英雄攻击创建按钮源码:https://github.com/iOSDevLog/ArenaOfValor

52760
来自专栏跟着阿笨一起玩NET

WEB免费打印控件推荐

要么购买成熟的打印控件,如果是大项目可以考虑,但如果项目只有几K到1、2W之间,这就麻烦了。

4.6K10

扫码关注云+社区

领取腾讯云代金券