目录

ArkUI页面滑动卡顿

问题现象

用户通常会滑动应用页面来查看当前不可见的内容,比如视频类、新闻类应用。为了保证有良好的用户体验,在滑动页面时期望看到页面流畅滑动,然而实际会存在滑动卡顿的现象,导致用户对应用程序的整体评价下降。

背景知识

问题定位

  1. 使用SmartPerf抓取或打开问题场景Trace文件,通过滑动Trace点H:APP_LIST_FLING确定应用滑动操作区间。

  2. 确定滑动区域内卡顿点。

    针对不同屏幕刷新率,Vsync信号的周期不同,120Hz对应8.33ms,90Hz对应11.11ms,60Hz对应16.67ms,滑动卡顿问题需要先确定Vsync信号的周期。

    查看滑动操作区间内的屏幕刷新率(找到render_service泳道中H:PreferredFrameRate对应的位置),如下图为120Hz,则在滑动区间内应用主线程接收Vsync信号周期(两个Vsync信号的起始点之间的间隔时间)为8.3ms,超出8.3ms的地方为卡顿点,需要分析排查其中耗时部分。

  3. 卡顿点可能存在以下情况:
    • 应用执行耗时操作:

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

    • 应用执行耗时的ArkTS业务逻辑:

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

    • 应用组件复杂,测量、布局耗时:

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

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

    • 应用以独立的帧率绘制更新UI页面:

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

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

    • 滑动期间binder调用过多:

      如下图所示,应用接收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组件多次测量布局:

      如下图所示,在滑动过程List组件有多次进行测量布局,测量布局耗时较多导致滑动卡顿。

分析结论

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

修改建议