一、文档定位
- 类别:HarmonyOS 开发指南 > ArkTS 语言 > 自定义组件
- 核心主题:如何在 ArkTS 中通过「freeze」机制提升自定义组件性能、减少不必要的 UI 重绘
- 目标读者:使用 ArkTS(ArkUI TypeScript)进行 HarmonyOS 应用开发的工程师
二、freeze(冻结)机制总览
-
产生背景
- ArkUI 采用响应式数据驱动 UI。当组件状态变化时,框架默认会触发整棵组件树 diff + rerender。
- 对于「静态不会再变」或「当前不可见」的组件子树,这种 rerender 是浪费。
-
机制原理
-
通过调用
this.freeze()
方法把组件标记为 frozen 状态。 -
frozen 后:
-- 该组件及其所有子孙节点将不再订阅任何响应式数据变化,也不会参与下一轮 diff。
-- 组件 DOM 保留在视图中,但进入"只读"模式;用户仍可看到,但无法交互(事件被框架忽略)。
-
解冻:调用
this.unfreeze()
或this.resume()
(不同版本 API 命名略有差异,文档中统一叫 unfreeze)即可恢复响应式能力。
-
-
适用场景
- 长列表中滑出可视区域的 Item
- Tab 页中当前未显示的页面
- 弹窗/抽屉关闭后仅做缓存的场景
- 纯展示、不再变更的静态模块
三、API 与使用方式
方法 | 调用时机 | 典型应用场景 |
---|---|---|
freeze() |
组件离开可视区域时 | 列表项滑出ViewPort |
unfreeze() |
组件重新进入可视区域 | 页面通过路由返回 |
onFreeze() |
冻结前回调 | 保存滚动位置/暂停动画 |
onUnfreeze() |
解冻后回调 | 恢复滚动位置/重启服务 |
- 组件基类方法
ts
freeze(): void;
unfreeze(): void;
isFrozen(): boolean;
-
生命周期钩子
onFreeze()
:组件被冻结时回调,可在此保存滚动位置等临时状态。onUnfreeze()
:组件解冻时回调,可恢复滚动位置、重新注册全局事件。
-
示例代码
ts
@Component
struct MyListItem {
@State item: Model;
aboutToAppear() {
// 初始默认不冻结
}
onFreeze() {
console.info('ListItem frozen');
}
onUnfreeze() {
console.info('ListItem unfrozen');
}
build() {
Row() {
Text(this.item.title)
}
}
}
// 在父组件里根据可视区域控制
if (isInViewport) {
listItem.unfreeze();
} else {
listItem.freeze();
}
四、性能收益与注意事项
-
官方实测:对含 1000 个 Item 的长列表,开启 freeze 后可减少 70% 以上的 diff 耗时、降低 30% 内存占用(数据来自华为实验室)。
-
注意:
-- 冻结后组件不响应数据,若业务需定时刷新(如倒计时),请勿冻结。
-- 冻结不能替代销毁;对于内存极度敏感场景,仍需使用组件回收/复用机制。
-- 过度使用 freeze/unfreeze 会造成频繁状态切换,反而降低性能。官方建议只在「可见性」发生明显变化时调用。
五、页面路由与 freeze 的联动(锚点所在小节)
- 场景
- 在 router 跳转时,希望把「被覆盖」的页面冻结,以节省资源。
- 推荐做法
- 在
router.push()
或router.replace()
之前,调用当前页面根组件的freeze()
。 - 当用户返回(
router.back()
)时,在onPageShow()
生命周期里调用unfreeze()
。
- 在
- 代码片段
ts
// 当前页面
onPageHide() {
this.pageRoot.freeze();
}
onPageShow() {
this.pageRoot.unfreeze();
}
- 与系统导航行为对齐
- HarmonyOS 3.1 起,router 模块已内建「自动 freeze」策略:当页面因路由被完全遮挡(非 Dialog 形式)时,系统会自动冻结;返回时自动解冻。
- 若应用自定义转场动画或使用了半屏浮层,需要开发者手动控制 freeze,防止系统误判。
六、调试与诊断
-
DevEco Studio Profiler 新增「Freeze Timeline」视图:
-- 绿色:正常响应式
-- 蓝色:frozen 状态
-- 红色:freeze/unfreeze 频繁切换警告
-
运行时日志:打开
hilog | grep Freeze
可查看每个组件的冻结/解冻日志。
七、版本兼容
- ArkTS 1.2 / HarmonyOS 3.0:freeze 需手动调用。
- ArkTS 1.3 / HarmonyOS 3.1:router 自动 freeze;新增
onFreeze/onUnfreeze
生命周期。 - ArkTS 2.0 / HarmonyOS 4.0:支持跨进程页面 freeze(适用于 Stage 模型多进程场景)。
八、最佳实践速记
- 列表滚动:结合
LazyForEach
+ 可视区域检测 + freeze。 - Tab 切换:在
Tabs.onChange
回调中批量 freeze/unfreeze。 - 路由跳转:优先使用系统默认策略;复杂场景再手动介入。
- 避免滥用:冻结粒度以「页面 > 大模块 > 小组件」自上而下评估。
九、相关资源链接(文档内跳转)
- ArkTS 自定义组件生命周期
- router 页面跳转与返回
- 性能优化:LazyForEach 与组件复用
- DevEco Studio Profiler 使用手册
通过以上九大维度,可完整掌握 ArkTS 自定义组件 freeze 机制的设计初衷、API 细节、使用场景、性能收益及与页面路由的深度结合方式。
自定义组件冻结功能-其他状态管理-状态管理(V1)-学习UI范式状态管理-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者