HarmonyOS 鸿蒙 Tabs组件开发中的性能优化技巧

44 阅读2分钟

在开发 Tabs 组件的过程中,我发现了一个有趣的问题:在使用 ForEach 遍历 TabContent 的时候,切换 tab 会导致页面闪烁。下面是具体的代码和解决方法。

问题描述

代码如下所示

@State selectIndex: number = 0; // 当前选中的 tab 索引

build() {
  Row() {
    Tabs({ index: this.selectIndex, controller: this.controller }) {
      ForEach(this.tabListData, (item: tabList, index) => {
        TabContent() {
          if (0 === this.selectIndex) {
            dayTwoDemo();
          } else if (1 === this.selectIndex) {
            Text(item.title).fontSize(50);
          } else if (2 === this.selectIndex) {
            Text(item.title).fontSize(50);
          } else if (3 === this.selectIndex) {
            Mine();
          }
        }.tabBar(this.tabBarItem(item));
      }, (item: tabList) => item.id.toString());
    }.barPosition(BarPosition.End)
    .onChange((index: number) => {
      this.selectIndex = index;
    });
  }
}

点击 tab 切换时,页面会闪烁,体验很差。通过分析代码发现,这个问题是由于 @State 修饰的变量 selectIndexForEach 的内容引用。每次 selectIndex 改变时,整个 ForEach 的内容都会重新渲染,导致了 TabContent 不必要的重绘。

问题分析

@State 是一个响应式装饰器,任何对其引用的代码都会因状态改变而重新计算。在 ForEach 中,selectIndex 被引用,因此每次切换 tab,即便只是当前 TabContent 的内容需要更新,所有 TabContent 也会被重新渲染。

解决方案

@State 修饰的变量从 ForEach 的内容中移除,改用 index 参数判断当前渲染的 TabContent,从而避免额外的重绘。 修改后的代码如下:

build() {
  Row() {
    Tabs({ index: this.selectIndex, controller: this.controller }) {
      ForEach(this.tabListData, (item: tabList, index) => {
        TabContent() {
          if (0 === index) {
            dayTwoDemo();
          } else if (1 === index) {
            Text(item.title).fontSize(50);
          } else if (2 === index) {
            Text(item.title).fontSize(50);
          } else if (3 === index) {
            Mine();
          }
        }.tabBar(this.tabBarItem(item));
      }, (item: tabList) => item.id.toString());
    }.barPosition(BarPosition.End)
    .onChange((index: number) => {
      this.selectIndex = index;
    });
  }
}

总结

优化关键点

  1. 避免在循环中直接使用响应式变量:在 ForEach 中避免直接引用 @State 修饰的变量,以减少不必要的重绘。
  2. 善用循环参数:利用循环 index 来判断渲染内容,替代响应式状态,优化性能。

收获与启发
在开发中,我们常常会不经意地滥用响应式变量,导致性能问题。理解其渲染机制,减少不必要的重绘,可以显著提升应用的用户体验。

希望这个经验分享能帮助你在开发中少踩坑!🎉