
基于ArkUI页面抛滑白块优化解决方案 精华
简介
使用imageKnife后仍存在滑动白块问题的场景,常规的解决方案是设置更大的cachedCount缓存数量,但这种方案可能会导致首屏白屏和内场占用增多,针对这个问题,本文将主要提供一种动态预加载的方案,首先介绍相关原理,针对两种技术组合即LazyForeEach+ImageKnife、Repeat+ImageKnife,再分别结合prefetch提供对应场景的开发案例,最终对比不同方案的测试数据。
原理介绍
Imageknife原理介绍
ImageKnife是专门为OpenHarmony打造的一款图像加载缓存库,它封装了一套完整的图片加载流程,开发者只需根据ImageKnifeOption配置相关信息即可完成图片的开发,降低了开发难度,提升了开发效率。
详细介绍可参考:https://gitee.com/openharmony-tpc/ImageKnife
LazyForeEach原理介绍
LazyForEach从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了LazyForEach,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用。
Repeat原理介绍
Repeat组件不开启virtualScroll开关时,Repeat基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在Repeat父容器组件中的子组件。Repeat循环渲染和ForEach相比有两个区别,一是优化了部分更新场景下的渲染性能,二是组件生成函数的索引index由框架侧来维护。
Repeat组件开启virtualScroll开关时,Repeat将从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。当在滚动容器中使用了Repeat,框架会根据滚动容器可视区域按需创建组件,当组件滑出可视区域外时,框架会缓存组件,并在下一次迭代中使用。
prefetcher原理介绍
prefetch是一种动态预加载技术,通过考虑滚动速度、屏幕上的项目数量等因素,动态的下载或取消下载资源,确保相关资源在需要时能立即显示。
详细介绍可参考:https://ohpm.openharmony.cn/\#/cn/detail/@netteam%2Fprefetcher
页面抛滑白块优化解决方案原理介绍
使用LazyForEach/Repeat遍历数据项,通过实现Prefetcher接口监听数据项,选择合适的时机预取数据,使用ImageKnife三方库实现具体的预取功能,并管理缓存。
场景案例
本解决方案针对两种技术组合即LazyForeEach+ImageKnife+prefetch(首页)、Repeat+ImageKnife+prefetch(分类),其中提供对应场景的开发案例,界面效果。
关键代码如下:
1.Prefetcher结合LazyForeEach实现瀑布流页面关键代码
2.Prefetcher结合Repeat实现瀑布流页面关键代码
3.Prefetcher必须要实现的接口
- IDataReferenceItem接口:要与Prefetcher一起使用的数据源项的接口。用作预取器数据源的数据源项或数组元素实现此接口。
核心代码:
- ITypedDataSource接口:可以链接到Prefetcher的数据源的接口。不需要修改数据源的实际实现。该接口确保数据源项类型与获取代理类型 IFetchAgent 匹配。
核心代码:
- IFetchAgent接口:该实现负责获取数据源项引用的数据。预取器构建器 API 确保数据源项 IDataReferenceItem 和绑定到预取器实例的获取代理具有匹配的类型。
核心代码:
性能分析
本案例中的页面一屏大概可以加载4至6条数据,每张图片的大小在200-300KB之间。针对使用LazyForeEach的场景,使用prefetch方案前后,快速滑动场景下的白块的数量效果对比如下:
表 1
使用prefetch方案前 | 使用prefetch方案后 |
在快速滑动的场景下,因为动态预加载能取消对快速划过的图片的数据请求,节省了大量的网络资源,从而减少了白块的数量。
示例代码
