【鸿蒙性能优化】基于List的滑动过程卡顿率问题分析&案例

101 篇文章 0 订阅
101 篇文章 0 订阅

1. 场景导入

卡顿率是用来判断页面操作是否流畅的一个指标,可以衡量应用启动、页面内滑动、页面转场操作是否流畅。在应用内使用ArkUI的List组件实现的列表,在页面滑动过程中,通过卡顿率来判断页面滑动是否流畅。

2.  性能指标

期望上屏时间是和帧率有关,如120FPS,期望上屏时间为1000ms / 120FPS = 8.3m

2.1 性能衡量起止点介绍

以大于300mm/s的速度,连续3次,每次半屏。List组件的抛滑过程,可以通过应用进程下的H:APP_LIST_FLING泳道标识。性能衡量的起点为第一次抛滑开始点,衡量的结束点为第三次抛滑的结束点。

Tip:尾动效阶段系统会进行降帧处理,所以如果统计卡顿率的情况,通常只会统计从抛滑开始到尾动效起点的这一阶段

3. 问题定位流程

3.1 常规定位前置流程

3.1.2 查看操作录屏辅助定位

处理三方应用问题时,可以优先查看操作录屏,查看操作场景,看能否发现一些有助于定位的信息,比如卡顿的页面布局情况、卡顿的现象等等。

3.1.2 Trace 抓取

滑动帧率Trace抓取请参考【附录1: 滑动帧率Trace抓取方法】。

3.2  问题定位思路

滑动卡顿类问题的通用定位思路为先根据性能工厂的测试报告确认卡顿率是否达标。如果不达标则确认单次抛滑的起止点,在Present Fence泳道找到超时帧,根据Trace信息进一步确认问题点,确认责任领域并对齐处理,处理流程如下图:

3.2.1 确认起止点

问题起止点确认

参考2.2 性能衡量起止点介绍

3.2.2 找问题点

3.2.2.1 判断卡顿帧进程

收藏Present Fence,H:APP_LIST_FLING,Frame泳道中的RS侧帧泳道和应用侧帧泳道。观察图形上屏超时是由应用侧帧超时引起的,还是由RS侧帧超时引起的。

应用进程问题

如下图,可以看到261,263,264帧耗时较长,最终264帧超时导致图形上屏时间超过了预期。

RS进程问题

RS进程丢帧可能是应用进程导致的,如上图RS侧丢帧,可以看到RS侧丢帧原因是由于应用进程的帧耗时较长,提交较晚导致。所以这种情况只分析应用侧丢帧原因即可。如果应用进程中没有丢帧且每帧耗时比较均匀,但是RS侧发生丢帧,则说明不是应用侧导致丢帧,此时只分析RS进程丢帧原因即可。

3.2.2.2 找丢帧Trace

点击卡顿帧查看详情,点击跳转应用进程

分析详细丢帧Trace

3.2.3 根本分析方法

应用侧的渲染流程如下图所示,了解ArkUI的渲染流程有助于我们定位应用侧的卡顿问题出现在哪个环节

阶段描述
Animation动画阶段,在动画过程中会对相应的组件标记脏区
Events事件处理阶段,比如手势事件处理。在手势处理过程中也会对组件标记脏区
UpdateUI组件在首次创建或状态变量变更时会标记为需要rebuild状态,在下一次Vsync过来时会通过View的方法生成相应的组件树结构和属性样式修改任务。
Measure执行组件的大小测算任务。
Layout执行组件的布局任务。
Render执行绘制任务,执行完成后会标记请求刷新RSNode绘制
SendMessage请求刷新界面绘制

应用进程丢帧分析

跟据应用帧跳转到应用侧的Trace泳道,初步分析每帧耗时较长的阶段。

261帧中H:LazyForEach predict | LazyForEach的耗时11.93ms,是懒加载组件预创建耗时较长导致丢帧。263帧中H:CustomNode:BuildRecycle耗时9.644ms,由于组件复用耗时长丢帧。

264帧中H:CreateTaskMeasure[ListItem][self:4426][parent:0]耗时18.384ms,分析这个组件节点下面的组件布局的Trace,由于组件结构复杂嵌套层级多导致丢帧。

序号所属泳道Trace点描述
1应用进程H:LazyForEach predictLazyForEach预处理
2应用进程H:CustomNode:BuildRecycle 自定义组件名自定义组件的复用,包含执行aboutToReuse方法的耗时
3应用进程H:CreateTaskMeasure[组件名][self:组件id][parent:父组件id] && H:Measure[组件名][self:组件id][parent:父组件id]执行组件的布局测量任务

通过ArkTS CallStack泳道,可以看到应用侧具体调用栈,进一步分析定位问题原因。如下图通过调用栈可以看到在递归进行组件复用时耗时较长,可以找应用看下是否组件嵌套层级过深;updateDirtyElement耗时长,应用侧可以分析下是否存在无关节点被触发更新;aboutToReuse耗时长可以看下应用侧该回调中是否存在耗时逻辑。

应用UI组件的嵌套情况,可以通过ArkUI Inspector查看。

经验总结:应用进程丢帧通常是组件结构嵌套层级深、耗时应用业务逻辑阻塞UI线程等问题导致。如果是UI结构复杂问题可以让应用通过减少嵌套层级、使用组件复用等方式优化。如果是有耗时业务逻辑,则可以通过将耗时逻辑放到Taskpool或Worker中优化。

RS进程丢帧分析

RS进程丢帧一般是由于界面结构过于复杂或者GPU负载过大等原因导致的。如果应用侧没有丢帧且每帧耗时比较平均,则可以初步判断应用侧没有问题,同时也可以通过应用侧Trace中H:SendCommands下的H:MarshRSTransactionData cmdCount查看应用提交的绘制指令树是否过多。

如下图RS侧丢帧原因是由于RS侧的H:RSUniRender:FlushFrame阶段耗时较长,此时可以找图形子系统进一步确认耗时根因。

经验总结:RenderService侧丢帧通常是应用侧UI线程阻塞提交绘制指令较慢导致,此时应当初步定位应用侧耗时长原因。如果应用侧无丢帧情况,绘制指令正常提交,则可以找图形子系统协助进一步分析丢帧原因。

4. 场景根因归档

4.1 耗时任务阻塞UI 主线程

Stage模型下的线程主要有三类:主线程、TaskPool、Worker。主线程主要用于执行UI绘制、处理应用代码逻辑,TaskPool和Worker的作用是为应用程序提供一个多线程的运行环境,用于处理耗时的计算任务或其他CPU密集型任务。

当主线程存在耗时的计算任务时,会使主线程阻塞,导致应用丢帧。

4.1.1 问题根因分析

Present Fence泳道中超时上屏的帧是269号帧提交太晚导致

通过帧详情跳转按钮进入到对应的Trace,UI线程没有提交绘制指令,但是处于运行状态

通过ArkTS Callstack泳道可以主要的耗时点在:SearchResultCommonList.ts,AlbumM.ts,index.ts文件中对数据的解析和处理。

4.1.2 优化方案

在List滑动过程中对数据进行处理耗时较长,占用大量CPU资源,导致主线程被阻塞,这部分数据处理的相关业务逻辑与UI绘制无关,但却长时间占用CPU资源,导致UI线程被阻塞丢帧。可以将该数据处理逻辑放到TaskPool中利用多核并行化处理优化。除应用侧的耗时逻辑外,某些与UI绘制无关的耗时系统接口调用也可以放到TaskPool中优化。

附录1 :滑动帧率Trace 抓取方法

Step1:电脑连接上设备,在DevEco Studio上打开Profiler

Step2:设备上运行需要测试的应用,在设备列表选择设备,选择要测试的应用,和主进程

Step3:创建Frame模板,并点击录制,待所有泳道都进入到recording状态后。

Step4:执行滑动操作

Step5:**操作完成,点击结束录制,待分析完成后,可以在泳道上看到trace数据

Step6:trace的路径点击Help -> Show Log in Explorer

返回到上一层,找到.insight文件下

附录2:List滑动场景通用Trace点说明

查看整体的帧信息

基于List组件的滑动过程中,在应用主进程下面会包含H:touchEventDispatch,H:APP_LIST_FLING,H:TRAILING_ANIMATION泳道。在Frame泳道下面有应用侧主线程帧泳道和Render Service帧泳道。在Render Service泳道下会有Present Fence泳道

刷新视图同步事件

序号Trace描述参数说明
1H:RunningCustomAnimation num:[1]自定义动画num中的数字表示动画的数量,如果大于0,表示还有动画在运行
2H:UITaskScheduler::FlushTask刷新UI界面,包括布局计算、渲染和提交等
3H:FlushLayoutTask执行布局任务
4H:CreateTaskMeasure[List][self:1643][parent:1642]创建测量任务组件名、组件ID、父组件ID
5H:Measure[List][self:1643][parent:1642][key:list]组件测量组件名、组件ID、父组件ID
6H:ListLayoutAlgorithm::MeasureListItem:17计算列表项的布局尺寸列表项索引
7H:CreateTaskLayout[List][self:1643][parent:1642]创建布局任务
8H:Layout[List][self:1643][parent:1642][key:list]执行布局任务组件名、组件ID、父组件ID
9H:FlushRenderTask 1执行渲染任务节点数量
10H:FrameNode[List][id:1643]::RenderTask单个渲染任务执行组件名,组件ID
11H:FlushMessages绘制消息
12H:SendCommands通知图形侧进行渲染
13H:MarshRSTransactionData cmdCount:39 transactionFlag [41088,384]提交的渲染数据进程ID、任务序号
14H:HandleOnAreaChangeEvent执行OnAreaChange任务一般耗时在us级
15H:HandleVisibleAreaChangeEvent执行OnVisibleChange任务一般耗时在us级

列表预创建

序号Trace描述参数说明
1H:Builder:BuildLazyItem构建LazyItem
2H:CustomNode:BuildItem [DTAvatar][self:2820][parent:2819]构建自定义组件组件名、组件ID、父组件ID
3H:Create[Image][self:2827]组件创建组件名、组件ID、父组件ID
4H:CustomNode:OnAppearOnAppear节点
5H:aboutToAppear组件初始化生命周期
6H:ExecuteJS运行ArkTS业务逻辑

列表预加载

序号Trace描述参数说明
1H:CreateTaskMeasure[ListItem][self:2791][parent:-1]创建并执行测量任务组件名、组件ID、父组件ID
2H:CreateTaskLayout[ListItem][self:2791][parent:-1]创建并执行布局任务组件名、组件ID、父组件ID
3H:FlushMessages & H:SendCommands发送消息通知图形侧进行渲染

鸿蒙全栈开发全新学习指南

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以要有一份实用的鸿蒙(HarmonyOS NEXT)学习路线与学习文档用来跟着学习是非常有必要的。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

本路线共分为四个阶段

第一阶段:鸿蒙初中级开发必备技能

在这里插入图片描述

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:gitee.com/MNxiaona/733GH

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

鸿蒙入门教学视频:

美团APP实战开发教学:gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值