OpenHarmony实战开发-合理处理高负载组件的渲染。

简介

在应用开发中,有的页面需要加载大量的数据,就会导致组件数量较多或者嵌套层级较深,从而引起组件负载加重,绘制耗时增长,如果不进行合理的处理,可能引起卡顿掉帧等性能问题。

问题场景

在日历应用的开发中,全年的日期页面需要加载一年中的所有日期,这样就最少需要365个Text组件用于显示日期。一次性绘制这么多的组件,时间会比较久,而且会耗费大量的资源,如果手机配置较差,可能会引起明显的卡顿或者转场动画的掉帧现象。

解决思路

由于一次性加载大量数据、绘制大量组件会导致卡顿,那么减少加载的数据量就是一种解决方法。但是由于业务需求,需要加载的数据总量和绘制的组件数量是不能减少的,那么只能想办法将数据进行拆分,将和数据相关的组件分成多次进行绘制。ArkTS中提供了DisplaySync(可变帧率),支持开发者设置回调监听,可以在回调里做一些数据的处理,在每一帧中绘制少量的数据,减少卡顿或者转场动画的掉帧现象。

优化示例

常规代码

通常情况下,会在进入页面后开始加载数据,即在aboutToAppear()中加载所有数据,并通过LazyForEach绘制所有的组件。

@Entry
@Component
struct Direct {
   
  ...
  // 初始化日历中一年的数据
  initCalenderData() {
   
    // 添加自定义trace标签,用于在trace抓取结果中查看相关运行时间信息
    hiTraceMeter.startTrace('push_data_direct', 1);
    for (let i = 1; i <= 12; i++) {
   
      // 获取每个月的日数据
      const monthDay: number[] = getMonthDate(i, this.currentYear);
      const month: Month1 = {
   
        month: i + '月',
        num: i,
        days: monthDay
      }
      this.contentData.pushData(month);
    }
    hiTraceMeter.finishTrace('push_data_direct', 1);
  }

  aboutToAppear() {
   
	...
    this.initCalenderData();
  }

  build() {
   
    Column({
    space: 12 }) {
   
      ...
      Grid() {
   
        LazyForEach(this.contentData, (monthItem: Month1) => {
   
          // 每个月的日期
          GridItem() {
   
            Flex({
    wrap: FlexWrap.Wrap }) {
   
			  ...
              // 日期信息
              ForEach(monthItem.days, (day: number) => {
   
                Text(day.toString())
                  ...
              })
            }
 		...
 		}
    }
    ...
  }
}

在上面的代码中,要在页面上显示一年中的所有日期,在aboutToAppear()方法中,将每个月的信息放入到一个数组里面,并通过LazyForEach通知Grid进行绘制。编译运行后,通过SmartPerfHost工具,抓取Trace,并查看耗时和掉帧率,如图1所示。其中push_data_direct是自定义添加的Trace标签,可以看到加载数据的开始时间和耗时,Expected Timeline是期望绘制一帧的时间,Actual Timeline是实际绘制一帧的时间。

图1 直接加载所有数据Trace图
在这里插入图片描述
通过图中信息可以看到,在aboutToAppear()中直接加载全部数据时,实际上就是在一帧中绘制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值