HarmonyOS鸿蒙Next中实现大数据量List的高效渲染?怎么做优化?

HarmonyOS鸿蒙Next中实现大数据量List的高效渲染?怎么做优化? List渲染10万条数据时卡顿,如何优化性能?

5 回复

优化的大量数据展示页面,使用分页和懒加载提高性能,代码如下:

/**
 * @author J.query
 * @date 2025/12/23 09:07
 * @email j-query@foxmail.com
 * Description: 优化的大量数据展示页面,使用分页和懒加载提高性能
 */

@Entry
@Component
struct LargeList {
  private data: string[] = [];
  private pageSize: number = 100; // 每页加载100条数据
  private currentPage: number = 0;
  private isLoading: boolean = false;
  private totalItems: number = 100000;
  private displayedItems: number = 0; // 当前显示的项目数量

  aboutToAppear() {
    // 初始化时只加载第一页数据
    this.loadDataPage();
  }

  // 分页加载数据
  loadDataPage() {
    if (this.isLoading || this.displayedItems >= this.totalItems) {
      return; // 防止重复加载或超出范围
    }

    this.isLoading = true;
    
    // 计算当前页的数据范围
    const startIndex = this.displayedItems;
    const endIndex = Math.min(startIndex + this.pageSize, this.totalItems);
    
    // 模拟异步加载,避免阻塞UI
    setTimeout(() => {
      for (let i = startIndex; i < endIndex; i++) {
        this.data.push(`条目${i}`);
      }
      
      this.displayedItems = this.data.length;
      this.isLoading = false;
    }, 16); // 大约60fps的时间间隔
  }

  build() {
    Column() {
      List() {
        ForEach(this.data, (item: string, index: number) => {
          ListItem() {
            Row() {
              Text(item)
                .height(50)
                .fontSize(16)
                .width('100%')
                .padding({ left: 16, right: 16 })
            }
            .height(50)
            .alignItems(VerticalAlign.Top)
          }
        }, (item: string) => item)
      }
      .onScrollIndex((startIndex: number, endIndex: number) => {
        // 当滚动到接近底部时加载更多数据
        if (endIndex >= this.displayedItems - 5 && !this.isLoading && this.displayedItems < this.totalItems) {
          this.loadDataPage();
        }
      })
      .cachedCount(this.data.length) // 启用缓存以提高性能
      .width('100%')
      .height('100%')
      
      // 加载更多指示器
      if (this.isLoading) {
        LoadingProgress()
        .width(40)
        .height(40)
        .visibility(Visibility.Visible)
      } else {
        Text('已加载 ' + this.displayedItems + ' / ' + this.totalItems + ' 项')
          .fontSize(12)
          .padding(8)
      }
    }
  }
}

cke_1779.png

更多关于HarmonyOS鸿蒙Next中实现大数据量List的高效渲染?怎么做优化?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


优化List的性能,建议考虑以下方法:

  1. 使用懒加载(LazyForEach)代替foreach渲染listitem:
    • 原理:仅渲染可视区域内的条目(如首屏6条),避免一次性加载全部数据。
LazyForEach(this.dataSource, (item: ItemType) => {
  ListItem() { CustomListItemComponent(item) }
}, (item) => item.id)
  1. 设置缓存列表项(cacheCount):
List() { ... }
// 最优解为绘制屏幕显示数量的一半
.cachedCount(5)
  1. 组件复用(@Reusable):
    • 原理:复用离开屏幕的组件,减少创建/销毁开销。
[@Reusable](/user/Reusable)
@Component
struct ReusableItem {
  aboutToReuse(params) { /* 更新数据 */ }
  build() { ... }
}

细微处:

// 布局扁平化:减少组件嵌套层级,用Column()替代冗余容器,配合.clip(true)限制绘制区域。
// 数据差异化更新:仅重渲染变化的条目,避免整体刷新(通过notifyDataChange(index)精准通知)。

1.List使用懒加载方式(LazyForEach)

2.可尝试使用@ohos.graphics.displaySync (可变帧率)分帧处理

3.List的Item使用绘制方式展示数据,不使用组件绑定

在HarmonyOS Next中,大数据量List的优化主要依靠LazyForEach懒加载机制。该机制仅渲染可视区域内的列表项,大幅减少内存占用和渲染开销。同时,应使用RecycleItem复用已滑出屏幕的列表项视图,避免重复创建。建议结合List组件的cachedCount属性预缓存少量相邻项以提升滑动流畅性。

在HarmonyOS Next中优化大数据量List渲染,核心在于减少同时渲染的节点数量。以下是关键优化方案:

  1. 使用LazyForEach替代ForEach

    • 仅渲染可视区域内的列表项,通过LazyForEach实现按需加载,这是处理10万级数据的首选方案。
  2. 设置listDirection为Axis.Vertical(默认)

    • 确保列表为垂直布局,便于系统进行滚动优化。
  3. 实现准确的getTotalCount和getKey

    • getTotalCount返回数据总量(如100000)。
    • getKey为每项生成唯一键,避免重复渲染。
  4. 优化列表项组件

    • 简化Item UI,减少嵌套视图。
    • 对复杂项使用@Reusable装饰器复用节点。
    • 避免在Item内部进行耗时操作。
  5. 控制列表项高度

    • ListItem设置固定高度或使用aspectRatio,有助于系统计算布局。
  6. 分页加载数据

    • 结合LazyForEach,监听滚动位置动态追加数据。

示例代码框架:

LazyForEach(this.dataArray, 
  (item: DataType) => {
    ListItem() {
      YourListItemComponent({ item: item })
    }
    .height(100) // 建议设置高度
  },
  (item: DataType) => item.id.toString() // 唯一键
)

通过LazyForEach的按需渲染机制,可显著提升大数据列表的滚动性能。

回到顶部