【高性能列表优化实例】HarmonyOS

 针对长列表加载这一场景,总共有如下五种优化手段。本实例使用前四种手段,通过这些优化手段的单个使用或组合使用,可以对列表渲染时间、页面滑动帧率、应用内存占用等方面带来优化,提升性能和用户体验:

  • 懒加载:提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、占用过多资源的问题,可以提升页面响应速度。
  • 缓存列表项:提供屏幕可视区域外列表项长度的自定义调节能力,配合懒加载设置可缓存列表项参数,通过预加载数据提升列表滑动体验。
  • 动态预加载:根据历史任务加载耗时情况,动态调整屏幕可视区域外数据预取数量,配合懒加载设置,可在列表不断滑动时,屏幕可视区外实时更新列表数据,通过预取和预渲染数据提升列表滑动体验
  • 组件复用:提供可复用组件对象的缓存资源池,通过重复使用已经创建过并缓存的组件对象,降低相同组件短时间内频繁创建和销毁的开销,提升组件渲染效率。
  • 布局优化:使用扁平化布局方案,减少视图嵌套层级和组件数,避免过度绘制,提升页面渲染效率。

 1、使用懒加载、缓存列表项、动态预加载和组件复用来优化列表加载性能

若开发者的应用中存在以下场景,并成为UI线程的帧率瓶颈,应该考虑使用组件复用机制提升应用性能:

  1. 滑动场景下对同一类自定义组件的实例进行频繁的创建与销毁。
  2. 反复切换条件渲染的控制分支,且控制分支中的组件子树结构比较复杂。

组件复用生效的条件是:

  1. 自定义组件被@Reusable装饰器修饰,即表示其具备组件复用的能力。
  2. 在一个自定义组件(父)下创建出来的具备组件复用能力的自定义组件(子),在可复用自定义组件从组件树上移除之后,会被加入到其父自定义组件的可复用组件缓存中。
  3. 在一个自定义组件(父)下创建可复用的子组件时,若可复用子节点缓存中有对应类型的可复用子组件的实例,会通过更新可复用子组件的方式,快速创建可复用子组件。
List({ scroller: this.menuScroller,space:0 }) {
        LazyForEach(this.menuData, (item: ProductListBean, index: number) => {
          ListItem() {
            MenuCompotent({ menuData: item})//这里的组件复用是指组件数不频繁的创建customerOrder和RenderOrder,放到组件缓存区拿过来复用,节省了组件的创建时间,提高性能
              .reuseId((item.timeDiscountInfo && item.timeDiscountInfo.name) ? 'isText' : 'noText')//组件结构根据if语句有变动,加入reuserId为结构创建ID提高复用效率,增加性能
              .onClick(() => {
              if (this.selectIndex != index) {
                let oleSelectIndex = this.selectIndex
                this.selectIndex = index
                this.menudata?.changeSelected(oleSelectIndex, this.selectIndex)
                this.onMenuSelected(this.selectIndex)
              }
              this.productScroller.scrollToIndex(index)
            })
          }
        },(item: ProductListBean, index: number)=> JSON.stringify(item)+index)
        ListItem().height(100)
      }
      .cachedCount(5)

2、MenuCompotent的组件复用

组件复用机制如下:

  1. 标记为@Reusable的组件从组件树上被移除时,组件和其对应的JSView对象都会被放入复用缓存中。
  2. 当列表滑动新的ListItem将要被显示,List组件树上需要新建节点时,将会从复用缓存中查找可复用的组件节点。
  3. 找到可复用节点并对其进行更新后添加到组件树中。从而节省了组件节点和JSView对象的创建时间。
@Component
@Reusable
export struct MenuComponent {
  @Prop menuData: ProductMenuList

  build() {
    Text(this.menuData.ListName)
          .height(34)
          .width('100%')
          .padding({ left: 8 })
      }.width('100%').height('100%')
  }
}

1.@Reusable:自定义组件被@Reusable装饰器修饰,即表示其具备组件复用的能力。

2.reuseId:用于标记自定义组件复用组,当组件回收复用时,复用框架将根据组件的reuseId来划分组件的复用组。如果只有一个复用的组件,可以不用设置reuseId。

性能收益

通过DevEco Studio的profiler工具分析复用前后的组件创建时间,可以得到应用使能组件复用后的优化情况,组件创建的时间平均从1800us降低到了570us。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值