目录

点击返回按钮响应慢

问题现象

点击页面返回按钮返回到上一状态时响应慢,过了一段时间界面才有变化。

背景知识

问题定位

  1. 使用DevEco Studio Frame分析工具抓取点击返回按钮过程的Trace信息,然后在抓取结果上方的输入框分别输入H:originEventHandle code:501、type=1找到mmi_service检测到手指离开屏幕、应用收到点击离手事件的Trace点。

    然后以应用收到点击离手事件的Trace点为起点,在上方输入框分别输入H:MarshRSTransactionData、H:RSMainThread::ProcessCommandUni、H:RSHardwareThread::CommitAndReleaseLayers找到应用第一次发送渲染请求、render_service处理渲染请求、render_service提交渲染结果的Trace点。计算Trace关键字的时间间隔,得到mmi_service、应用、render_service各阶段耗时如下图表所示,耗时主要集中在应用部分。

    mmi_service

    应用

    应用->render_service(应用结束点到render_service起始点)

    render_service

    总和

    3.3ms

    251.7ms

    13.2ms

    25.0ms

    293.2ms

  2. 分析应用阶段Trace信息,发现耗时主要包含执行自定义组件的aboutToAppear、组件测量部分,可通过ArkTS Callstack泳道查看耗时部分的堆栈信息,确认耗时原因。

    aboutToAppear部分的堆栈信息中可看到执行了XXXPage组件的aboutToAppear函数,该函数中调用了一个load方法较耗时。

    组件测量部分的堆栈中可看到有初始化渲染大量组件,组件创建较耗时。

    结合前后两者信息可知,在点击返回按钮时,应用创建了XXXPage组件,该组件包含大量子组件,执行aboutToAppear和测量时耗时较多,导致响应慢的问题。

分析结论

点击返回按钮时,应用创建组件、执行耗时操作,导致响应慢的问题。

修改建议

import { taskpool } from '@kit.ArkTS';
import { BusinessError } from '@ohos.base';

// 循环打印模拟耗时任务
@Concurrent
async function timeConsumingTask() : Promise<number> {
  console.info('startTask');
  for (let i = 0; i < 100000; i++) {
    console.info(`number:${i}`);
  }
  return 1;
}

@Entry
@Component
struct TaskPoolDemoPage {
  build() {
    RelativeContainer() {
      Button('执行耗时任务')
        .onClick(() => {
          taskpool.execute(timeConsumingTask).then((result: Object) => {
            console.info(`result:${result as number}`);
          }).catch((error: BusinessError) => {
            console.error(`Failed to execute task: errCode is ${error.code}, errMessage is ${error.message}`);
          });
        })
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}