深入解析优化UNI-APP的列表卡顿问题,优化前后相差92倍!

1,440 阅读2分钟

框架:基于VUE2的UNI-APP

实习工作期间,在使用UNI-APP开发微信小程序的时候遇到了个很奇怪的问题。

在列表项仅渲染了200+后,清空列表项会存在明显的卡顿。

通过Performance工具分析可以看到。耗时主要发生在flushCallbacks这个回调函数中。

image.png

再次查看渲染执行结构,发现微信小程序的渲染递归回调的。也就是说,只有当最里层的组件渲染完之后,才会执行回调通知上一层组件。

所以,我初步认为问题就出现在了组件层级上,因此我去除了组件化后了,再次进行测试。

去除组件化后,渲染时长也确实降下来了。

但是我问过很多大佬,他们都说组件化虽然有影响,但不至于影响这么大。而且在日常团队开发中,如果剔除了组件化,那么将会增加后期的维护成本。

所以,尽管这个问题看似已经解决了,但我觉得还是不够完美。而且很多人使用uniapp开发时也没有出现这个问题。

于是我再次对代码渲染数据进行分析。

通过断点调试发现,变更的内容确实只有147个

image.png

但是,当渲染跑到了notify函数时,发现了依赖项的数量有问题。deps数组记录的依赖项中的subs数组居然高达了5000+个依赖项

企业微信截图_20230722174719.png

最后通过多次断点调试检查,发现到了可疑点。基本在每个组件的内部都存在这个主题颜色的依赖项。并且在页面进行渲染的时候,也触发了这个依赖项的更新。

image.png

检查项目代码发现,主题色这个对象,是通过全局mixin导入到了每个组件里面,也就是说,每个组件的内部都会存在这个主题色的计算属性。

所以才会出现短短一个列表项,却出现了5000+个依赖项的原因(其中大部分都是这个主题色的相关依赖项)

image.png

为了校验猜想,我把这个全局mixin给注释了。最后发现,耗时确实也降下来了(24784.1ms降到了265.4ms)

image.png

再次查看依赖项,subs的依赖项也确实降下来了。

image.png

总结解决方法:

    1.去除组件化开发(因为v-for每生成一个组件,都会存在全局mixin的数据,所以去除组件化也可以达到避免依赖增多的问题)

    2.剔除全局mixin(或把数据放到data中,并且对数据进行冻结,避免出发响应式更新)

最后引用vue官方的一句话。各位使用全局mixin时,一定要!!!!格外小心!!!! image.png

再送上一张关于微信小程序的setData约束建议

企业微信截图_16899116749457.png