HarmonyOS 鸿蒙Next Lottie动画在列表中滚动卡顿如何优化
HarmonyOS 鸿蒙Next Lottie动画在列表中滚动卡顿如何优化
【问题现象】
列表中有Lottie动画,当Lottie动画播放时列表滚动卡顿,当Lottie动画播放结束之后,列表滚动恢复正常。如下图:
问题代码如下:
// 使用三方库[@abner](/user/abner)/refresh中的组件ListView构造列表
ListView({
items: this.array, //数据源 数组,可以任意类型,自定义对象[],number[],string[]……
itemLayout: this.itemLayout, //转成你需要的对象
listAttribute: (attr) => {
attr.edgeEffect = EdgeEffect.Spring //设置阻尼效果
}
})
/**
- Describe:条目布局
* @param item 数据对象
* @param index 数据索引
*/
@Builder
itemLayout(): void {
Row() {
AnimatorLottieBase({
imagePath: “lottie/round_frame95/images/”,
path: “lottie/round_frame95/data.json”,
animateName: ‘https://ali-dev-system.lrscloud3.com/avatarframe/round_frame95.zip’,
autoplay: true,
loop: true, // 当loop为true时,滚动异常卡顿
})
.height(50)
.width(50)
Blank(100)
}
}
【背景知识】
- Lottie是一个适用于OpenHarmony的动画库,它可以解析Adobe After Effects软件通过Bodymovin插件导出的JSON格式的动画,并在移动设备上进行本地渲染;
- 卡顿是一种在视觉上表现为画面不流畅、停顿或延迟的现象,它可能由多种因素引起,丢帧是其中一个重要原因;当设备性能不足时,可能无法及时处理和渲染所有的帧,从而导致丢帧,进而引发卡顿。
【定位思路】
1、用户同一时间加载过多动画,导致性能过载
观察到界面中的Lottie动画数量很多,通过日志打印发现进入动画界面时会初始化个动画,这样的定义方式会将统一渲染服务进程占满,导致进程在刚进入该界面时不仅要处理动画的初始化,还要处理List列表的滑动,这时设备性能不足,从而丢帧引发卡顿。
2、多余的动画渲染没有及时销毁,造成不必要的性能损耗
该界面同时加载了个动画,显示在界面中的15个动画在播放,其余30+个在界面之外的动画也同时在播放。
【解决方案】
1、合理使用动画生命周期,在首次进入界面时,不过多初始化构造多余动画
上文发现使用ListView会在首次进入界面时构造全部数量(50)的动画,造成性能过载。使用List组件替代三方库[@abner](/user/abner)/refresh中的组件ListView后,通过日志可以看到首次进入只构造了在界面中显示的14个,随着慢慢向下滑动屏幕,使下方的动画进入界面内,List组件才会构造该动画,卡顿现象得到缓解。
代码示例如下:
List({ space: 10, initialIndex: 0 }) { // list上下树逻辑,ondisappear在出界面不会走;api13有需求做;
ForEach(this.array, (item: number) => {
ListItem() {
AnimatorLottieBase({
imagePath: "lottie/round_frame95/images/",
path: "lottie/round_frame95/data.json",
animateName: 'https://ali-dev-system.lrscloud3.com/avatarframe/round_frame95.zip',
autoplay: false,
loop: true, // 当loop为true时,滚动异常卡顿
index: item,
})
.height(50)
.width(50)
}
}, (item: string) => item)
}.width('90%')
.scrollBar(BarState.Off)
2、动画滑出界面时,控制动画暂停,降低性能损耗
给画布组件添加onVisibleAreaChange属性,当该组件不可见时暂停该动画,可见时播放该动画。
代码示例如下:
.onVisibleAreaChange([0.0, 1.0],
(isVisible: boolean, currentRatio: number) => {
if (isVisible) {
console.log('onVisibleAreaChange:' + 'play' + ' index: ' + this.index)
this.animationItem?.play();
} else {
console.log('onVisibleAreaChange:' + 'stop' + ' index: ' + this.index)
this.animationItem?.stop();
}
})
【总结】
- 通过上文两步的调整,卡顿现象在基本场景下已经得到解决;该界面可共同展示个循环播放的lottie动画,可满足大部分应用场景。
- 处理丢帧问题一般需要以下四个步骤:
1、识别卡顿
首先使用AppAnalyzer检测应用是否存在性能问题,如果检测存在丢帧问题,然后使用Frame Profiler、SmartPerf Host等工具录制Trace,查看应用平均帧率、丢帧率等,同时查看丢帧发生的位置。
2、分析丢帧原因
可以通过分析Trace,查看卡顿帧的详细信息。最后查看函数调用栈,查看是否存在耗时函数。
3、选择优化方案
根据步骤分析的丢帧原因,选择适合的优化方案。
4、验证优化效果
优化完成后需要重新测试验证丢帧问题是否得到解决,这里可以再次通过步骤来确认优化效果。
针对HarmonyOS鸿蒙Next中Lottie动画在列表中滚动卡顿的问题,以下是一些优化建议:
- 优化动画效果:精简Lottie动画,避免过度复杂的动画导致性能下降。确保动画的流畅性和连贯性,以提升用户体验。
- 使用LazyForEach技术:在列表中,使用LazyForEach懒加载技术替换ForEach,避免一次性加载所有元素,从而提升首帧绘制速度和响应性能。
- 布局优化:采用扁平化布局,减少视图嵌套层级,避免过度绘制。这有助于降低渲染开销,提升滚动流畅度。
- 利用缓存机制:对Lottie动画或其所在的组件进行缓存,以减少重复渲染的负载。
- 合理使用系统资源:优化应用的内存和CPU使用,避免资源泄漏和过度占用。
通过上述方法,可以有效提升HarmonyOS鸿蒙Next中Lottie动画在列表中的滚动流畅度。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。