实现思路
1、首先,确定应用中是否存在包含复杂UI的长列表场景。如果列表项的UI结构简单,@Reusable 带来的提升可能不明显。但如果列表项是复杂的卡片,包含图片、按钮、多个布局嵌套,那么它就是优化的绝佳对象。
2、在自定义组件的定义前,添加 @Reusable 装饰器。这相当于告诉ArkUI编译器:“这个组件的实例可以被缓存和复用”。
3、实现 aboutToReuse 生命周期,与组件首次创建时调用的 aboutToAppear 不同,aboutToReuse 会在组件从缓存池中被取出、准备复用时调用。
4、在父组件中,像往常一样使用 LazyForEach 来渲染数据。ArkUI框架会自动识别被 @Reusable 标记的组件,并在后台管理其复用逻辑,开发者无需在父组件中编写额外的复用代码。
应用场景
社交应用的信息流:每一条动态都是一个复杂的卡片,包含头像、昵称、正文、图片、点赞/评论按钮等。快速滑动时,@Reusable 可以让滑动如丝般顺滑。
电商应用的商品列表:商品卡片通常包含主图、标题、价格、标签等多个元素,结构复杂。@Reusable 能有效提升用户浏览商品列表的体验。
实现效果

完整代码
注意案例中
// ItemData.ets
export class ItemData {
id: string;
title: string;
content: string;
imageUrl: string; // 使用资源管理器中的像素图
constructor(id: string, title: string, content: string, imageUrl: string) {
this.id = id;
this.title = title;
this.content = content;
this.imageUrl = imageUrl;
}
}
// ReusableListItem.ets
import { ItemData } from './ItemData';
/**
* 使用 [@Reusable](/user/Reusable) 装饰器标记此组件为可复用组件
*/
[@Reusable](/user/Reusable)
@Component
export struct ReusableListItem {
// 使用 @Prop 接收从父组件传递的数据
@Prop itemData: ItemData;
// 内部状态,例如用于模拟一个“喜欢”的状态
@State isLiked: boolean = false;
aboutToAppear() {
console.info(`[Lifecycle] Component ${this.itemData.id} aboutToAppear. First time created.`);
}
/**
* 组件复用时触发的生命周期函数
* @param params 从父组件传入的新参数,与 @Prop 对应
*/
aboutToReuse(params: Record<string, Object>) {
// 必须在这里更新 @Prop 变量,否则UI不会刷新
this.itemData = params.itemData as ItemData;
// 如果有其他需要根据数据重置的状态,也可以在这里处理
this.isLiked = false;
console.info(`[Lifecycle] Component ${this.itemData.id} aboutToReuse. Reusing existing instance.`);
}
build() {
Column() {
Row() {
Image($r('app.media.background')) // 假设有一个本地图标资源
.width(48)
.height(48)
.borderRadius(24)
.margin({ right: 12 })
Column() {
Text(this.itemData.title)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.fontColor('#333333')
Text(this.itemData.content)
.fontSize(14)
.fontColor('#666666')
.margin({ top: 4 })
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
}
.width('100%')
.alignItems(VerticalAlign.Top)
.padding(16)
Divider().color('#F1F1F1')
Row() {
Button(this.isLiked ? '已喜欢' : '喜欢')
.fontSize(14)
.backgroundColor(this.isLiked ? '#FF6B6B' : '#E1E1E1')
.fontColor(this.isLiked ? Color.White : '#333333')
.onClick(() => {
this.isLiked = !this.isLiked;
})
Blank()
Button('分享')
.fontSize(14)
.backgroundColor('#007DFF')
.fontColor(Color.White)
}
.width('100%')
.padding({ left: 16, right: 16, bottom: 16 })
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius(12)
.margin({ left: 12, right: 12, top: 8, bottom: 8 })
.shadow({
radius: 4,
color: '#1F000000',
offsetX: 0,
offsetY: 2
})
}
}
// Index.ets
import { ItemData } from './ItemData';
import { ReusableListItem } from './ReusableListItem';
// 模拟大量数据
const generateData = (): ItemData[] => {
let data: ItemData[] = [];
for (let i = 0; i < 100; i++) {
data.push(new ItemData(
`id_${i}`,
`这是第 ${i + 1} 个标题`,
`这是第 ${i + 1} 个卡片的内容描述,它可能很长,用来测试文本溢出和多行显示的效果。组件复用技术能够显著提升此类复杂列表的滚动性能。`,
'' // 图片URL留空,使用本地资源
));
}
return data;
}
@Entry
@Component
struct Index {
// 使用 @State 管理数据源
@State private dataSource: ItemData[] = generateData();
build() {
Column() {
Text('[@Reusable](/user/Reusable)性能优化示例')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 10 })
List({ space: 0 }) {
// 注意注意注意:这里一定要使用 LazyForEach 进行数据懒加载 ,我这里为了方便只写了ForEach
ForEach(this.dataSource, (item: ItemData) => {
// 直接使用被 [@Reusable](/user/Reusable) 标记的组件
// ArkUI 框架会自动处理其复用逻辑
ReusableListItem({ itemData: item })
}, (item: ItemData) => item.id) // keyGenerator 必须提供,用于标识唯一项
}
.listDirection(Axis.Vertical)
.scrollBar(BarState.Off)
.edgeEffect(EdgeEffect.Spring)
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
}
}
更多关于HarmonyOS鸿蒙Next中使用@Reusable优化组件性能的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,@Reusable装饰器是优化组件性能、特别是解决长列表滚动卡顿问题的关键工具。其核心原理是组件复用,而非传统的销毁后重建。
当列表滚动、组件滑出视窗时,被@Reusable标记的组件不会被销毁,而是被框架回收至一个复用池中。当需要渲染新的同类组件时,框架会优先从池中取出实例,直接应用新的数据(通过aboutToReuse生命周期)进行更新,跳过了完整的初始创建过程。
如何使用:
- 装饰组件:在自定义组件类前添加
@Reusable装饰器。@Reusable @Component struct ReusableListItem { // 组件内容 } - 实现关键生命周期:在组件内实现
aboutToReuse方法。当组件被复用时,框架会调用此方法并传入新的参数。在此方法中,你必须更新组件的所有状态(@State,@Link等)和通过参数传入的数据,以正确显示新内容。@Reusable @Component struct ReusableListItem { @State itemData: string = ''; aboutToReuse(params: { data: string }) { // 必须在此处更新状态,以响应复用后的新数据 this.itemData = params.data; } build() { // 使用 this.itemData 构建UI } }
性能收益与注意事项:
- 显著减少开销:避免了组件初始化、视图树创建等大量计算,使列表滚动极其流畅。
- 状态管理是关键:
aboutToReuse是复用的核心,必须在此方法中完成所有状态同步。如果状态更新不全,会导致UI显示错误数据。 - 适用场景:最适合结构相似、仅内容数据变化的列表项组件。对于结构差异巨大的组件,复用意义不大。
- 与
@Component共存:@Reusable是@Component的增强,两者需同时使用。
通过正确应用@Reusable,可以极大提升列表等高频创建/销毁场景的渲染性能,实现丝滑滚动体验。

