ArkTS 组件复用与性能:@Builder、@Reusable 与懒加载的正确用法

举报
yd_295436472 发表于 2026/11/06 10:38:30 2026/11/06
【摘要】 ArkTS 组件复用与性能:@Builder、@Reusable 与懒加载的正确用法列表一滑就掉帧、页面越用越卡,很多时候问题不在算法,而在组件的创建与复用方式上。本文结合 ArkTS 的 @Builder、@Reusable 与懒加载机制,梳理一套可落地的组件性能优化思路,代码以关键片段为主,可按项目需要调整。 一、先分清三种“复用”解决的是不同问题@Builder:把一段 UI 抽成可...

ArkTS 组件复用与性能:@Builder、@Reusable 与懒加载的正确用法

列表一滑就掉帧、页面越用越卡,很多时候问题不在算法,而在组件的创建与复用方式上。本文结合 ArkTS 的 @Builder、@Reusable 与懒加载机制,梳理一套可落地的组件性能优化思路,代码以关键片段为主,可按项目需要调整。

一、先分清三种“复用”解决的是不同问题

  • @Builder:把一段 UI 抽成可复用的构建函数,减少重复代码,解决的是“写起来省事”。
  • @Reusable:让组件实例在列表滚动时被复用而不是反复创建销毁,解决的是“创建成本高”。
  • 懒加载(LazyForEach):只渲染可见区域附近的列表项,解决的是“一次建太多”。

三者经常一起出现,但不要互相替代:@Builder 本身不复用实例,LazyForEach 不减少单个组件的创建开销,@Reusable 不决定哪些数据先渲染。

二、@Builder:抽公共 UI,但别滥用参数

@Builder 适合抽出“结构相同、数据不同”的 UI 片段,比如列表项里的标题行、空状态、加载占位。

@Builder
function TitleRow(title: string, sub: string) {
  Row() {
    Text(title).fontSize(16).fontWeight(FontWeight.Bold)
    Text(sub).fontSize(12).fontColor(Color.Gray)
  }
}

两点注意:其一,@Builder 函数内部不要持有会频繁变化的状态,状态变化会触发整个 Builder 重新执行;其二,嵌套层级过深时,优先拆成独立组件而不是继续套 Builder,否则调试和性能分析都会变难。

三、@Reusable:给列表项一个“第二生命”

在长列表中,滑出屏幕的组件实例如果直接销毁,滑回来又要重新创建,布局、图片解码、状态初始化的开销会反复发生。@Reusable 标记的组件可以在复用池里“换一身数据”继续用。

@Reusable
@Component
struct ListItem {
  @State item: ItemData = new ItemData();
  aboutToReuse(params: Record<string, Object>) {
    // 复用前更新数据:重置图片、清理旧状态
    this.item = params.item as ItemData;
  }
  build() {
    Row() {
      Image(this.item.cover).width(64).height(64)
      Text(this.item.title)
    }
  }
}

复用时最容易踩的坑是“脏状态”:上一个数据残留的图片、选中的勾选框、未取消的定时器,都会在复用后原样出现。aboutToReuse 里要显式重置这些状态;aboutToAppear 与 aboutToDisappear 则适合做资源的申请与释放,而不是数据更新。

四、LazyForEach:先算“看得见的”

LazyForEach 只对可见区域附近的数据项调用创建逻辑,配合 IDataSource 使用:

LazyForEach(this.dataSource, (item: ItemData) => {
  ListItem({ item })
}, (item: ItemData) => item.id)

关键在第三个参数 keyGenerator:它决定了复用时如何匹配新旧数据。key 必须稳定唯一,用数组下标做 key 会在插入、删除后导致错位复用,出现“图片和标题对不上”的诡异问题。数据量变化时,调用数据源的 notifyDataAdd / notifyDataDelete 等方法通知刷新,而不是整体重建。

五、一个可落地的检查清单

  • 列表超过一屏,优先确认是否用了 LazyForEach 而不是 ForEach。
  • 列表项结构复杂(图片 + 多行文本 + 交互控件),给组件加 @Reusable,并在 aboutToReuse 中重置状态。
  • 重复出现的 UI 片段抽成 @Builder 或独立组件,但不要把状态塞进 Builder 参数里反复传递。
  • 图片加载用缓存与占位图,避免复用瞬间出现旧图闪烁。
  • 用性能分析工具看“组件创建次数”而不是只看帧率:创建次数降下来,帧率自然稳。

结语

组件性能优化没有银弹,@Builder 管代码复用,@Reusable 管实例复用,LazyForEach 管渲染范围,三者各司其职。先定位瓶颈在“建太多”“建太贵”还是“重复建”,再选对应的手段,列表滑动才会真正顺滑起来。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。