刷新过程中,ForEach键值生成函数未设置导致的闪屏问题
问题现象
下拉刷新时,应用产生卡顿,出现闪屏问题。

@Builder
private getListView() {
  List({
    space: 12, scroller: this.scroller
  }) {
    // 使用懒加载组件渲染数据
    ForEach(this.newsData, (item: NewsData) => {
      ListItem() {
        newsItem({
          newsTitle: item.newsTitle,
          newsContent: item.newsContent,
          newsTime: item.newsTime,
          img: item.img
        })
      }
      .backgroundColor(Color.White)
      .borderRadius(16)
    });
  }
  .width('100%')
  .height('100%')
  .padding({
    left: 16,
    right: 16
  })
  .backgroundColor('#F1F3F5')
  // 必须设置列表为滑动到边缘无效果,否则无法触发pullToRefresh组件的上滑下拉方法。
  .edgeEffect(EdgeEffect.None)
}

可能原因
ForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即(item: Object, index: number) => { return index + '__' + JSON.stringify(item); }。可参考键值生成规则。
在使用ForEach的过程中,若对于键值生成规则的理解不够充分,可能会出现错误的使用方式。错误使用一方面会导致功能层面问题,例如渲染结果非预期,另一方面会导致性能层面问题,例如渲染性能降低。
解决措施
在ForEach第三个参数中定义自定义键值的生成规则,即(item: NewsData, index?: number) => item.id,这样可以在渲染时降低重复组件的渲染开销,从而消除闪屏问题。可参考ForEach组件使用建议。

@Builder
private getListView() {
  List({
    space: 12, scroller: this.scroller
  }) {
    // 使用懒加载组件渲染数据
    ForEach(this.newsData, (item: NewsData) => {
      ListItem() {
        newsItem({
          newsTitle: item.newsTitle,
          newsContent: item.newsContent,
          newsTime: item.newsTime,
          img: item.img
        })
      }
      .backgroundColor(Color.White)
      .borderRadius(16)
    }, (item: NewsData) => item.newsId);
  }
  .width('100%')
  .height('100%')
  .padding({
    left: 16,
    right: 16
  })
  .backgroundColor('#F1F3F5')
  // 必须设置列表为滑动到边缘无效果,否则无法触发pullToRefresh组件的上滑下拉方法。
  .edgeEffect(EdgeEffect.None)
}

运行效果如下图所示。

总结
当出现应用闪屏相关问题时,首先定位可能出现的原因,分别测试是否为当前原因导致。定位到问题后尝试使用对应解决方案,从而消除对应问题现象。
应用连续点击场景下,通过计数器优化动画逻辑。
Tabs页签切换场景下,完善动画细粒度,提高流畅表现。
ForEach刷新内容过程中,根据业务场景调整键值生成函数。
本文主要引用参考HarmonyOS官方文档


李洋蛟龙腾飞
1 声望0 粉丝

鸿蒙开发先行者