HarmonyOS 教学实战(三):列表分页、下拉刷新与性能优化(让列表真正“丝滑”)

在上一篇《HarmonyOS 教学实战(二)》中,我们已经让应用具备了:

  • 网络请求

  • 本地缓存

  • 离线兜底

  • 完整 Store 设计

但只要你的数据一多,列表就一定是性能重灾区

真实项目中,80% 的卡顿都来自:

❌ 列表一次性加载

❌ 下拉刷新逻辑混乱

❌ 滚动时频繁重建组件

这一篇,我们专门解决这些问题。


一、这一篇我们要解决哪些真实痛点?

围绕一个真实列表页面,完成 3 件事:

  1. 📄 列表分页加载(上拉加载更多)

  2. 🔄 下拉刷新(重新请求第一页)

  3. 🚀 列表性能优化(可复用组件 + 状态收敛)

完成后,你的列表会具备:

数据多也不卡、刷新快、滚动顺


二、先改接口:支持分页返回

假设后端接口升级为:

复制代码
GET /api/tasks?page=1&pageSize=10

返回格式:

复制代码
{
  "list": [
    { "id": 101, "title": "学习 HarmonyOS" }
  ],
  "hasMore": true
}

三、第一步:升级网络 Service(分页支持)

修改 service/TaskService.ets

复制代码
export interface PageResult<T> {
  list: T[]
  hasMore: boolean
}

export class TaskService {
  static async fetchTasks(
    page: number,
    pageSize: number
  ): Promise<PageResult<Task>> {
    const httpRequest = http.createHttp()

    const response = await httpRequest.request(
      `https://example.com/api/tasks?page=${page}&pageSize=${pageSize}`,
      { method: http.RequestMethod.GET }
    )

    const data = JSON.parse(response.result as string)

    return {
      list: data.list.map(item => new Task(item.id, item.title)),
      hasMore: data.hasMore
    }
  }
}

四、第二步:升级 Store(分页核心逻辑)

分页的核心逻辑必须放在 Store,而不是 UI。

修改 model/TaskModel.ets

复制代码
@ObservedV2
export class TaskStore {
  tasks: Task[] = []
  page: number = 1
  pageSize: number = 10
  hasMore: boolean = true
  loading: boolean = false
  refreshing: boolean = false

  async refresh() {
    if (this.refreshing) return

    this.refreshing = true
    this.page = 1

    const result = await TaskService.fetchTasks(this.page, this.pageSize)
    this.tasks = result.list
    this.hasMore = result.hasMore

    this.refreshing = false
  }

  async loadMore() {
    if (!this.hasMore || this.loading) return

    this.loading = true
    this.page++

    const result = await TaskService.fetchTasks(this.page, this.pageSize)
    this.tasks = this.tasks.concat(result.list)
    this.hasMore = result.hasMore

    this.loading = false
  }
}

教学重点

  • refresh():只管第一页

  • loadMore():只管追加

  • UI 只需要调用,不参与逻辑判断


五、第三步:页面中接入下拉刷新 & 上拉加载

修改 pages/Index.ets

复制代码
@ComponentV2
struct Index {
  @Local store = new TaskStore()

  @Once
  async init() {
    await this.store.refresh()
  }

  build() {
    Column() {
      Refresh({ refreshing: this.store.refreshing }) {
        List() {
          ForEach(this.store.tasks, (item: Task) => {
            TaskItem({ task: item, onDelete: () => {} })
          }, item => item.id.toString())

          if (this.store.hasMore) {
            ListItem() {
              Text(this.store.loading ? '加载中...' : '上拉加载更多')
                .onAppear(() => this.store.loadMore())
            }
          }
        }
      }
    }
  }
}

📌 onAppear 是分页加载的关键

📌 不需要监听滚动位置

📌 非常稳定


六、第四步:列表性能优化(重点)

1️⃣ 使用 @ReusableV2 优化列表项

复制代码
@ReusableV2
@ComponentV2
export struct TaskItem {
  @Param task: Task
  @Event onDelete: (id: number) => void

  build() {
    Row() {
      Text(this.task.title)
      Button("删除")
        .onClick(() => this.onDelete(this.task.id))
    }
  }
}

📌 ArkUI 会自动复用组件结构

📌 滚动时不会频繁销毁/重建


2️⃣ 避免 ListItem 中使用 @Local 状态

❌ 错误示例:

复制代码
@Local checked = false

会导致每个 Item 都维护自己的状态,极易卡顿。

✔ 正确做法:
状态上移到 Store 或 Model


3️⃣ 控制刷新粒度(状态收敛)

避免这样的写法:

复制代码
@Local store = new TaskStore() // 整个 store 变 → 全列表刷新

更优方式是:

  • 列表只依赖 tasks

  • loading 状态放在 footer


七、第五步:缓存 + 分页怎么配合?

推荐策略:

场景 行为
首次进入 读缓存 → 再 refresh
下拉刷新 丢弃缓存
上拉加载 不写缓存
退出页面 保存当前列表

📌 不要每一页都缓存

📌 缓存的是"可用数据",不是"中间态"


八、常见分页性能坑(必看)

❌ 坑 1:List + Column 嵌套

会导致全部子项提前创建

✔ 用 List + ListItem


❌ 坑 2:key 不稳定

复制代码
key = index // 非常危险

✔ 使用业务 id


❌ 坑 3:刷新 & 加载同时进行

✔ Store 中用标志位严格限制


九、现在你的 App 已经是"工业级列表"了

你已经具备:

✔ 分页加载

✔ 下拉刷新

✔ 状态隔离

✔ 高性能列表

✔ 可扩展 Store 结构

这已经是 90% 商业 App 列表的实现水平

相关推荐
UWA7 小时前
哪些因素和参数会影响Bloom的性能开销
性能优化·script·rendering
侑虎科技7 小时前
Unity IL2CPP的GC原理
性能优化
柠果7 小时前
HarmonyOS震动反馈开发——提升用户体验的触觉交互
harmonyos
柠果7 小时前
HarmonyOS数据持久化最佳实践——Preferences首选项存储详解
harmonyos
柠果7 小时前
HarmonyOS纯音测听实现——专业听力检测功能开发
harmonyos
柠果7 小时前
HarmonyOS深色模式适配实战——主题切换与WCAG对比度标准
harmonyos
柠果7 小时前
HarmonyOS权限管理实战——麦克风、震动等敏感权限申请
harmonyos
爱吃大芒果7 小时前
Flutter 列表优化:ListView 性能调优与复杂列表实现
开发语言·hive·hadoop·flutter·华为
乾元8 小时前
网络遥测(Telemetry/gNMI)的结构化建模与特征化体系—— 从“采集指标”到“可被 AI 推理的状态向量”
运维·服务器·网络·人工智能·网络协议·华为·ansible