Skip to content
Last updated: 2023-05-21
<

前言

最近遇到的一些微信小程序性能开发案例,记录一下心得。

项目背景,是一个控制家电的应用。包括家庭、房间、设备、场景等维度。其中设备列表是以卡片列表形式展示。卡片可以看到设备的名称、图标,开关、离线状态;交互还蛮多,可以直接控制,也可以点击弹出控制框进行更多的控制,还可以长按进行拖拽排序、批量编辑。界面还受 websocket 推送的影响,需要实时刷新列表。

miniprogram

项目刚开始,都只是十来条的测试设备数据,负责设备模块的同事,尽职完成产品的需求。效果酷炫的同时还兼顾了丝滑。

没想到同事离职后,领导忽然要做压力测试。大家蓦然发现,才增加到 40 个设备,原来运行得好好的应用,就开始明显卡顿;增加到 80 个设备后,已卡到怀疑人生。包括首次加载,以及非常简单的操作交互。

尽管一个房间同时放上百个设备的场景不多,但 40 个设备就明显卡顿,实在很难向领导解释。努力优化吧!

基本的优化

首先找到官方文档,所有相关的优化实践都研究一番,能做的都做一遍。收效有,但不明显。

除了官方文档提及的,还使用过的主要措施,包括:

  • 引入官方的长列表组件 recycle-view,好像是快了,但页面调用变复杂了。最主要是没有达到预期的效果,而且还会出现一些莫名的缺项问题,快速滚动时的体验也因为分屏加载的原因而较差。官方文档也语焉不详,颇难进一步优化。再一想,其实 100 个卡片,每行 4 个,这规模也没有那么长。

  • 使用独立的渲染列表。即将业务数据和渲染用的数据区分开来,为渲染单独映射一个列表,以免因为冗余数据导致 setData 的数据量过大。

  • 使用分页加载的方式,将渲染列表,从一维数据变为二维数据,以便逐页进行 setData 操作,这个方案在前期优化成效相对显著,保证了第一屏快速展示,体验马上就相来了。在用户发呆时,列表余下部分就默默加载完了。

  • 在多处地方使用节流控制,包括鼠标事件处理器、高频查询接口、高频的全列表刷新、websocket 响应等。

  • 引入类似 lodash._get 的方法,精确到字段地对列表进行 diff,减少渲染压力。

被忽略的大鱼

也不能说是大 BUG,毕竟是正经的代码逻辑。

排查代码时,偶然发现一些用于循环的基础卡片组件,直接使用 store 的数据绑定。这样引用,确实能实现跨组件的状态响应式同步,然而随着业务功能细化,store 越来越大时,这种滥用就让状态管理不堪重负了,更新非常慢,而且循环中把一大块数据都连带着,setData 也频繁在控制台输出超出 1024KB 的 warning

改用直接参数传递,实现基础组件与业务解耦,性能翻倍提升。可以找领导交差了。

Released under the MIT License.