问题现象
当用户点击应用页面上的内容(比如按钮),从一个页面进入到另一页面过程,出现卡顿的情况。
背景知识
- 屏幕刷新率:显示设备每秒钟更新屏幕内容的次数,其决定了Vsync信号周期,120Hz对应8.33ms,90Hz对应11.11ms,60Hz对应16.67ms。
- Vsync信号:垂直同步信号,设备的屏幕通过固定频率发送Vsync信号来控制每一帧绘制操作的时机。
- 在HarmonyOS中,图形系统采用统一渲染模式,遵循典型流水线模式。在渲染流程中,应用侧首先响应消费者的屏幕点击等输入事件,处理完成后提交给Render Service。Render Service协调GPU等资源处理,最终将图像送到屏幕上显示,整个流程应用侧和Render Service侧都可能出现卡顿,导致最终用户观察到丢帧,具体可看渲染流程。
- DevEco Profiler:集成在DevEco Studio中的性能调优工具,提供场景化的性能调优功能体验,目前版本提供六大特性解决快速定界、效率提升、内存分析、内核分析和卡顿分析相关问题,帮助应用开发者定位到问题代码,更多详细内容可看使用Profiler进行性能调优。
页面切换关键Trace点如下:
关键字 | 所处线程 | 描述 |
H:ABILITY_OR_PAGE_SWITCH | 应用主线程 | 页面切换。 |
H:PostAndWait | render_service | 渲染服务提交绘制任务并等待绘制完成。 |
H:RSSurfaceRenderNodeDrawable::OnDraw[窗口名] | RSUniRenderThread | 窗口绘制。 |
H:onCreateTexture | RSUniRenderThread | 创建纹理。 |
- ArkUI Inspector:DevEco Studio提供的布局分析工具,可用于查看应用在真机上的UI显示效果,能够快速分析定位状态变量、组件嵌套层次、UI界面布局存在的问题等。
问题定位
以某应用页面切换卡顿为例,相关定位过程如下:
- 使用DevEco Profiler Frame模板抓取应用页面切换的Trace信息,根据Trace关键字H:ABILITY_OR_PAGE_SWITCH确定页面切换的过程,查看该过程应用主线程Trace信息,发现主线程在该过程并没有多次触发绘制送显,因此推测不是应用主线程卡顿导致的页面切换卡顿,而是Render Service卡顿。

- 查看render_service线程,发现渲染服务线程在接收Vsync信号处理时,长时间处于PostAndWait阶段(175ms左右),在等待RsUniRenderThread子线程唤醒。

而RsUniRenderThread子线程在执行绘制时,应用窗口的绘制时长时间处于Running状态,时长达到了179ms,同时有创建8191x7176大小的纹理,推测是页面负载过高,并且与图片有关。


- 使用ArkUI Inspector抓取页面的布局,发现页面层级不深、布局不复杂,Image组件的图片为http图片资源。

将图片下载后查看得知该图片的分辨率达到了10800*7176,图片分辨率较大,超出了Image组件DMA策略生效的图片大小范围,在绘制时会出现纹理上传,导致渲染服务绘制耗时,出现卡顿。

分析结论
应用页面的资源图分辨率过大,在绘制时会进行纹理上传,绘制耗时多,导致页面切换卡顿。