1. 控制状态刷新 🔄
核心思想 :状态变量是UI刷新的触发器,滥用会导致性能劣化。
优化策略:
- 精简状态变量 :
普通变量别用@State
装饰,避免不必要的渲染。
ini
// ❌ 冗余状态变量
@State count: number = 0;
// ✅ 改用普通变量
private count: number = 0;
- 最小化状态共享范围 :
按需选择装饰器:
-
- 组件内独享 →
@State
- 父子组件共享 →
@Prop
/@Link
- 跨层级共享 →
@Provide
/@Consume
- 组件内独享 →
scss
// 父子组件共享示例
@Component
struct Parent {
@State message: string = "Hello";
build() {
Column() {
Child({ msg: this.message }) // 通过@Prop传递
}
}
}
@Component
struct Child {
@Prop msg: string; // 子组件接收
build() {
Text(this.msg)
}
}
- 精准刷新监听 :
用@Watch
监听数据变化,避免全局刷新。
less
@State @Watch('onCountChange') count: number = 0;
onCountChange() {
if (this.count > 10) this.updateUI(); // 条件触发刷新
}
2. 控制渲染范围 🎯
核心思想 :减少不必要的组件渲染和布局计算。
优化策略:
- 懒加载长列表 :
用LazyForEach
替代ForEach
,只渲染可视区域。
javascript
LazyForEach(this.data, (item) => {
ListItem({ item })
}, (item) => item.id)
- 组件复用 :
相同布局的自定义组件通过reuseId
复用节点。
scss
@Component
struct ReusableItem {
@Reusable reuseId: string = "item_template"; // 标识可复用
build() { ... }
}
- 分帧渲染 :
大数据量分批次渲染,避免主线程阻塞。
scss
// 分帧加载1000条数据
loadDataBatch(start: number) {
const batch = data.slice(start, start + 20);
requestAnimationFrame(() => this.renderBatch(batch));
}
3. 优化组件绘制 ✏️
核心思想 :减少布局计算和属性注册开销。
优化策略:
- 避免生命周期内耗时操作 :
aboutToAppear()
中别做网络请求等重操作。
scss
aboutToAppear() {
// ❌ 避免
heavyNetworkRequest();
// ✅ 改用异步
setTimeout(() => heavyNetworkRequest(), 0);
}
- 固定宽高减少计算 :
明确尺寸的组件避免自适应布局。
scss
// ✅ 固定宽高跳过Measure阶段
Image($r("app.media.icon"))
.width(100).height(100)
4. 使用并发能力 ⚡
核心思想 :主线程只负责UI,耗时任务交给子线程。
优化策略:
- 多线程处理 :
CPU密集型用TaskPool
,I/O密集型用Worker
。
javascript
// TaskPool示例
import { taskpool } from '@ohos.taskpool';
@Concurrent
function computeHeavyTask() { ... }
taskpool.execute(computeHeavyTask).then((res) => {
// 更新UI
});
- 异步优化 :
用Promise
或async/await
避免阻塞。
csharp
async loadData() {
const data = await fetchData(); // 异步请求
this.updateUI(data);
}
5. 减少布局节点 🌳
核心思想 :节点越少,渲染越快。
优化策略:
- 用
@Builder
替代轻量组件 :
无状态组件用@Builder
更高效。
scss
@Builder
function IconButton(icon: Resource) {
Button() {
Image(icon)
}
}
// 调用
IconButton($r("app.media.home"))
- 删除冗余容器 :
移除不必要的Stack/Column/Row
嵌套。
scss
// ❌ 冗余嵌套
Column() {
Column() {
Text("Hello")
}
}
// ✅ 扁平化
Text("Hello")
6. 延时触发操作 ⏳
核心思想 :非关键操作延迟执行,提升启动速度。
优化策略:
- 动态加载模块 :
用import()
按需加载资源。
javascript
// 点击时才加载模块
Button("Load Feature")
.onClick(async () => {
const module = await import("./HeavyModule");
module.run();
})
7. 优化动画帧率 🎞️
核心思想 :60fps是流畅动画的生命线。
优化策略:
- 使用系统动画组件 :
优先用animateTo
而非手动控制帧。
ini
animateTo({ duration: 300 }, () => {
this.rotateAngle = 90; // 系统自动插值
})
- 减少动画复杂度 :
用transform
替代top/left
避免重排。
kotlin
// ✅ GPU加速
Image($r("app.media.logo"))
.transform({ rotate: this.angle })
8. 感知流畅优化 ✨
核心思想 :用户感知 > 真实性能。
优化策略:
- 预加载关键资源 :
启动时预先加载首屏图片/数据。
javascript
aboutToAppear() {
preloadImages(["/res/image1.png", "/res/image2.png"]);
}
- 骨架屏占位 :
数据加载前展示占位UI。
scss
if (this.isLoading) {
LoadingSkeleton() // 骨架屏组件
} else {
RealContent()
}
结尾:性能优化是持续旅程 🛣️
性能优化不是一蹴而就,而是持续迭代的过程。记住三个黄金原则:
- 精准刷新:谁变刷谁,别动全局。
- 主线程轻量化:耗时操作全扔子线程。
- 节点精简:布局层级越浅越好。
希望这些案例能帮你少踩坑!如果有问题,欢迎在评论区讨论。
一起打造极致流畅的鸿蒙应用吧! 💪