Appearance
ArkTS 性能最佳实践
ArkTS 性能优化的核心原则:编译期优化、减少运行时开销、利用 AOT 特性。
1. ArkTS 性能优化全景
编译期优化 (AOT)
├── 静态类型 → Hidden Class
├── 无 any → 跳过类型检查
├── 无 eval → 代码优化
└── 无 var → 变量提升消除
运行时优化
├── 对象池 → 减少 GC
├── 对象不变性 → 缓存优化
├── 按需渲染 → LazyForEach
└── 减少 build 复杂度 → 首屏优化2. 类型优化
2.1 避免 any
typescript
// ❌ 任何类型,编译器无法优化
let data: any = fetchData()
// ✅ 具体类型,编译器生成 Hidden Class
let data: ResponseData = fetchData()
// ✅ Record 类型,精确约束
let dict: Record<string, number> = {}2.2 使用 Record 代替 {} 字面量
typescript
// ❌ 普通对象,性能较差
let obj: object = { name: '小明', age: 25 }
// ✅ Record,Hidden Class 优化
let obj: Record<string, string | number> = {
name: '小明',
age: 25
}2.3 类型推断优先
typescript
// ✅ 编译器自动推导,减少冗余声明
let name = '小明' // string
let count = 42 // number
let items = ['a', 'b'] // string[]
// 需要显式声明的场景:
// 1. 接口/类型别名
// 2. 函数返回值
// 3. 可能为 null/undefined
let age: number | null = null3. 对象优化
3.1 Hidden Class 原理
JavaScript/V8/ArkCompiler 使用 Hidden Class(隐藏类)优化对象属性访问:
对象创建 → 确定属性布局 → 生成 Hidden Class → 快速属性访问
{ name: '小明', age: 25 }
↓
Hidden Class: { [0]: name(offset 0), [1]: age(offset 8) }
↓
属性访问: O(1) 直接内存偏移访问3.2 保持对象形状不变
typescript
// ✅ 推荐:对象形状一致
function process1() {
let obj1 = { name: '小明', age: 25 } // Class A
let obj2 = { name: '小红', age: 20 } // 同一 Class A
// obj1 和 obj2 共享 Hidden Class,快速
}
// ❌ 不推荐:动态添加属性
function process2() {
let obj = { name: '小明' } // Class A
obj.age = 25 // 创建 Class B!
let obj2 = { name: '小红', age: 20 } // Class C
// obj、obj2 不在同一 Hidden Class,需要类型检查
}3.3 使用 as const
typescript
// 减少运行时分配
const CONFIG = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3
} as const // 编译期确定,运行时共享同一引用4. 数组操作优化
4.1 避免频繁 push/pop 在 build 中
typescript
@Component
struct Index {
@State items: string[] = []
// ❌ 在 build 中修改数组
build() {
this.items.push('item') // ❌ 不应在 build 中操作
}
// ✅ 在回调或生命周期中修改
addItem() {
this.items.push('item') // ✅ @State 检测到变化
}
}4.2 使用 LazyForEach 替代 ForEach
typescript
// ❌ ForEach:全量渲染(数据量大时卡顿)
ForEach(this.largeList, (item) => {
ListItem(item)
})
// ✅ LazyForEach:按需渲染(推荐)
LazyForEach(this.dataSource, (item) => {
ListItem(item)
})4.3 数组不可变性
typescript
// ✅ 通过不可变赋值触发刷新
@Component
struct Index {
@State list: string[] = ['a', 'b', 'c']
addItem(item: string) {
// ❌ 直接 push 可能不触发刷新
this.list.push(item)
// ✅ 创建新数组触发刷新
this.list = [...this.list, item]
// ✅ 或者替换数组引用
this.list = [...this.list]
}
}5. 字符串优化
5.1 字符串拼接
typescript
// ❌ 循环拼接字符串(频繁创建新对象)
let result = ''
for (let i = 0; i < 10000; i++) {
result += 'item'
}
// ✅ 使用 Array.join(更高效)
let result = Array.from({ length: 10000 }, () => 'item').join('')5.2 字符串模板
typescript
// ✅ 模板字符串(编译期优化)
let name = '小明'
let greeting = `Hello, ${name}!`
// ✅ 多行字符串
let html = `
<div>
<p>${name}</p>
</div>
`6. 函数调用优化
6.1 减少函数调用开销
typescript
// ❌ 循环中频繁调用函数
for (let i = 0; i < 10000; i++) {
this.formatItem(items[i]) // 函数调用开销
}
// ✅ 内联处理(减少调用开销)
for (let i = 0; i < 10000; i++) {
let item = items[i]
let formatted = `${item.name} - ${item.value}` // 内联
}6.2 使用静态方法
typescript
class Utils {
// 静态方法:无需实例化
static formatDate(date: Date): string {
return date.toISOString()
}
static isEmpty(value: any): boolean {
return value === null || value === undefined || value === ''
}
}
// 调用
Utils.formatDate(new Date())
Utils.isEmpty('')7. build() 函数优化
7.1 build() 中的限制
| 限制 | 原因 |
|---|---|
| 不能写 console.log | build 只执行 UI 描述 |
| 不能定义局部变量 | 编译期优化需要纯描述 |
| 不能直接调用非 @Builder 函数 | 保持纯描述语义 |
7.2 优化 build 复杂度
typescript
// ❌ build 中嵌套太多组件(渲染慢)
build() {
Column() {
Row() { // 第2层
Column() { // 第3层
Row() { // 第4层
Column() { // 第5层...
Text('...')
}
}
}
}
}
}
// ✅ 提取为子组件
@Component
struct Header { ... }
@Component
struct Content { ... }
@Component
struct Footer { ... }
build() {
Column() {
Header()
Content()
Footer()
}
}8. 面试高频考点
Q1: Hidden Class 是什么?如何优化?
回答:ArkCompiler 在编译期为对象生成隐藏类(属性布局),运行时通过内存偏移快速访问属性。优化方式:保持对象形状一致、使用 Record 类型、使用 as const。
Q2: build() 函数有哪些限制?
回答:只能包含 UI 描述代码,不能写 console.log、不能定义局部变量、不能直接调用非 @Builder 装饰的函数。原因是 build 需要编译期纯描述优化。
Q3: ForEach 和 LazyForEach 的区别?
回答:ForEach 全量渲染,适合少量数据;LazyForEach 按需渲染(只渲染可视区域),配合 IDataSource 使用,长列表必用。
🐱 小猫提示:性能优化的核心思路就是**"能编译期做的绝不放到运行时"**。记住 Hidden Class、LazyForEach、build 复杂度这三个关键词。