用户通常会滑动应用页面来查看当前不可见的内容,比如视频类、新闻类应用。为了保证有良好的用户体验,在滑动页面时期望看到页面流畅滑动,然而实际会存在滑动卡顿的现象,导致用户对应用程序的整体评价下降。
页面滑动相关Trace关键字如下:
关键字 | 说明 |
|---|---|
H:APP_LIST_FLING | 手指按下开始拖动到抬手后的惯性滚动及最后尾动效的抛滑全过程,用于标记应用页面滑动。 |
H:PreferredFrameRate | 屏幕刷新率,在render_service泳道中。 |
H:ReceiveVsync | 接收Vsync信号。 |
H:FlushDirtyNodeUpdate | 刷新标脏的组件,当状态变量变化时,比如宽度和高度,组件需要重新布局刷新。 |
H:CustomNodeUpdate 组件名 | 组件刷新,当状态变量变化时触发。 |
H:CreateTaskMeasure[组件名][self:组件ID][parent:父组件ID] | 创建组件的测量任务,确定组件的宽、高。 |
H:CreateTaskLayout[组件名][self:组件ID][parent:父组件ID] | 创建组件的布局任务,确定组件的位置。 |
H:SendCommands | 发送指令,通知图形侧进行渲染。下方H:MarshRSTransactionData表示提交渲染数据给渲染服务。 |
H:HandleOnAreaChangeEvent | 处理组件区域变化事件,组件的大小、位置发生时触发。 |
H:HandleVisibleAreaChangeEvent | 处理可见区域变化事件,组件可见面积(即组件在屏幕显示区的面积,只计算父组件内的面积,超出父组件部分不会计算)与组件自身面积的比值与设置的阈值接近时触发。 |
H:LazyForEach predict | LazyForEach预处理。 |
H:List predict | List预处理。 |
H:Builder:BuildLazyItem | 构建LazyItem。 |
H:CustomNode:BuildItem[组件名][self:组件ID][parent:父组件ID] | 构建自定义组件。 |
H:ExecuteJS | 运行ArkTS业务逻辑 |
H:ViewPU.viewPropertyHasChanged 组件名 状态变量名 N | 状态变量更新,N表示该状态变量更新后影响的组件数量。该Trace关键字需要运行hdc shell param set persist.ace.debug.enabled 1命令然后重启应用才能生效。 |
针对不同屏幕刷新率,Vsync信号的周期不同,120Hz对应8.33ms,90Hz对应11.11ms,60Hz对应16.67ms,滑动卡顿问题需要先确定Vsync信号的周期。
查看滑动操作区间内的屏幕刷新率(找到render_service泳道中H:PreferredFrameRate对应的位置),如下图为120Hz,则在滑动区间内应用主线程接收Vsync信号周期(两个Vsync信号的起始点之间的间隔时间)为8.3ms,超出8.3ms的地方为卡顿点,需要分析排查其中耗时部分。

应用在两侧接收Vsync信号处理存在长时间的Running,如下图所示,此处应用在执行耗时操作,会导致卡顿。

如下图所示,应用在接收Vsync信号处理时耗时20.1ms,远远超出了8.3ms,耗时主要在H:ExecuteJS,运行ArkTS业务逻辑。

如下图所示,应用在接收Vsync信号处理时耗时10ms,超出了预期时间8.3ms,耗时主要集中在组件ListItem测量部分。

使用ArkUI Inspector工具查看该组件的层级,可看到该组件层级达到了10+,组件层级较多。

如下图所示,应用在接收Vsync信号处理时耗时14.3ms,超出了预期时间8.3ms,耗时主要集中在H:DispatchDisplaySync,推测应用进行了降帧率。

可以使用DevEco Profiler Frame分析工具抓取该过程Trace信息,查看DispatchDisplaySync部分应用的调用栈,如下图可看到耗时集中在应用so文件的帧回调函数,应用有请求自绘制内容绘制频率,该频率较低导致滑动卡顿问题。

如下图所示,应用接收Vsync信号的周期超过90ms,远大于预期的11.11ms,耗时主要集中在大量binder调用。

如下图所示,应用在接收Vsync信号处理时耗时10.1ms,超出了预期时间8.3ms,耗时主要集中在H:FlushDirtyNodeUpdate,状态变量变化,组件更新耗时多。

查看滑动过程中Trace信息,发现有大量状态变量更新、节点刷新,同时在日志中可以看到有大量State variable 'xxx' has changed during render日志打印,这是由于组件渲染绘制时有更新状态变量,一直触发节点刷新,导致滑动卡顿丢帧问题。

11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error! 11889-11889 C03947/com.exam...AceStateMgmt com.examp...lication E [(100000:100000:scope)] FIX THIS APPLICATION ERROR: @Component 'XXXXXX'[11248]: State variable 'XXXXXX' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error!
如下图所示,在滑动过程List组件有多次进行测量布局,测量布局耗时较多导致滑动卡顿。

ArkUI页面滑动卡顿的原因有: