目录

ArkUI页面点击响应慢

问题现象

点击页面内容后需要等待一段时间才进入新页面,有延迟。

背景知识

问题定位

以点击某应用首页跳转到详情页,点击响应慢问题为例,按整体流程拆分总耗时,确定各模块耗时,具体如下:

  1. 多模输入模块耗时为手指离开屏幕到应用收到该事件的时间。用SmartPerf打开Trace文件,在上方搜索框中输入H:originEventHandle code:501找到手指离开屏幕的地方。

    接着以该点为起始点,在应用包名泳道中往后查看几ms范围内的Trace关键字H:DispatchTouchEvent XXX type=1,找到应用收到该事件的地方,得到该部分耗时为1.5ms。

  2. 应用模块耗时起点为应用收到手指离开屏幕的事件,终点为应用从当前页面开始跳转到新页面时第一次发送绘制请求的结束点。

    手指离开屏幕事件的地方为上述多模输入模块耗时的结束点。应用第一次发送绘制请求的地方可以通过应用收到手指离开屏幕的事件后第一次接收Vsync信号(Trace关键字为H:ReceiveVsync)中发送绘制请求(关键字为H:SendCommands)的结束点来确定,同时该点会在页面切换Trace关键字H:ABILITY_OR_PAGE_SWITCH的起始点附近。

    计算应用收到手指离开屏幕的事件和该点之后应用第一次提交绘制请求的时间可确定应用模块处理耗时142.5ms。

  3. 渲染服务模块耗时为渲染服务处理应用发送的渲染请求到将GPU处理的渲染结果提交到显示硬件的时间。

    渲染服务处理应用发送的渲染请求可以通过应用模块耗时的结束点来确定。在应用包名泳道上方有个Actual Timeline泳道,在应用接收Vsync信号、提交绘制请求处会有对应的一段Trace点(以数字呈现),点击后在下方显示框中点击render_service右侧的跳转箭头可以找到渲染服务处理页面有变化第一帧数据的地方。

    然后以render_service这次处理Vsync信号为起点,根据now(时间戳),在RSHardwareThread泳道中找到render_service将该帧GPU处理的渲染结果提交到显示硬件的地方,最终得到渲染服务模块耗时15.7ms。

    最终得到如下耗时拆分结果,耗时主要集中在应用模块。

    多模输入模块

    应用

    应用->渲染服务(应用结束点到渲染服务起始点)

    渲染服务

    总和

    1.5ms

    142.5ms

    6.0ms

    15.7ms

    165.7ms

  4. 分析耗时占比较多的模块,按上述步骤分析,耗时最多的部分在应用,应用侧耗时场景可能有:
    • 场景一:执行业务代码耗时:

      框选Trace中应用主进程该阶段的运行状态,发现耗时主要在Running部分,查看该阶段的Trace信息,得知其中一部分是加载NewsPage页面,还有另一部分没有Trace点,无法看到在执行什么业务流程。

      使用Profiler工具抓取该过程的Trace信息,发现应用在执行dispatchJson方法,该方法耗时占比较多。

    • 场景二:http请求耗时:

      查看该阶段应用包名泳道Trace,发现耗时主要在http请求部分。

      结合问题发生时的Hilog日志,根据Trace信息中的TaskID可以看到问题发生时http请求总耗时7.237秒,因此点击响应慢。
      06-26 10:37:48.275 21779 26289 I C015B0/应用包名/NETSTACK: [http_exec.cpp:418] taskid=-2147483646, size:89, dns:0.073, connect:0.000, tls:0.000, firstSend:0.219, firstRecv:0.000, total:7236.370, redirect:0.000, errCode:0, RespCode:200, httpVer:2, method:POST, osErr:0

分析结论

  1. 应用主线程在收到点击事件响应处理时,执行较耗时的业务代码,导致点击响应慢的问题。
  2. 应用通过http请求获取资源,请求耗时过久导致整体响应慢。

修改建议

  1. 可将耗时操作迁移到异步任务中处理,避免阻塞主线程,提升应用的响应速度,参考使用多线程能力。
  2. 优化服务侧性能或采用预加载服务提前请求资源,提升响应速度。