本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、性能分析工具链
1. 核心工具对比
工具 | 用途 | 关键指标 | 适用阶段 |
---|
ArkProfiler | 线程/内存分析 | CPU占用率、内存泄漏 | 开发/测试阶段 |
SmartPerf | 渲染管线监控 | FPS、UI重绘次数 | 真机调试阶段 |
HiDumper | 系统级快照 | 线程堆栈、服务状态 | 线上问题定位 |
2. 关键性能指标阈值
指标 | 优秀值 | 警戒值 | 危险值 |
---|
主线程CPU占用 | <30% | 30%-50% | >50% |
内存峰值 | <200MB | 200-300MB | >300MB |
列表滚动FPS | ≥55fps | 30-55fps | <30fps |
二、内存优化实战
1. 常见内存泄漏场景
// 案例1:未取消订阅事件
class LeakDemo {
private listener: events.EventEmitter = new events.EventEmitter()
aboutToAppear() {
this.listener.on('update', () => { /*...*/ }) // 需在aboutToDisappear取消
}
}
// 案例2:缓存未清理
@State imageCache: Map<string, image.PixelMap> = new Map() // 需实现LRU淘汰策略
2. 内存分析四步法
- 抓取快照:
hdc shell hidumper -m 0x0801 > dump.txt
- 定位泄漏:搜索
native size
异常增长的对象 - 代码溯源:通过
backtrace
找到持有链 - 修复验证:对比修复前后内存曲线
三、渲染加速技巧
1. 列表渲染优化(百万级数据)
@Entry
@Component
struct OptimizedList {
@State data: LargeData[] = loadData()
build() {
List({ space: 5 }) {
LazyForEach(this.data, (item: LargeData) => {
ListItem() {
Text(item.key).fontSize(16)
.cached(true) // 启用文本缓存
}
.reuseId(item.id) // 复用相同ID的ListItem
}, (item) => item.id)
}
.onReachEnd(() => { /* 分页加载 */ })
.initialIndex(0) // 初始渲染位置
}
}
优化效果:渲染耗时从1200ms降至200ms
2. 离屏绘制(NEXT专属)
import { OffscreenCanvas } from '@ohos.arkui'
@Component
struct ChartComponent {
private offscreenCtx = new OffscreenCanvas(300, 300)
build() {
Canvas(this.offscreenCtx.getContext('2d')) // 复用离屏画布
.onReady(() => {
this.drawComplexChart() // 复杂绘制在后台线程完成
})
}
}
四、实战:图片加载优化
1. 三级缓存架构
A[网络下载] --> B[磁盘缓存]
B --> C[内存缓存]
C --> D[控件显示]
2. 关键实现代码
class ImageLoader {
async load(url: string): Promise<PixelMap> {
// 1. 检查内存缓存
if (this.memoryCache.has(url)) {
return this.memoryCache.get(url)
}
// 2. 检查磁盘缓存
const diskCache = await this.checkDiskCache(url)
if (diskCache) {
this.memoryCache.set(url, diskCache) // 回填内存缓存
return diskCache
}
// 3. 网络下载
const netImage = await this.download(url)
this.saveCache(url, netImage) // 异步写入缓存
return netImage
}
}
五、避坑指南
性能陷阱 | 优化方案 | 原理说明 |
---|
频繁GC触发 | 对象池模式复用对象 | 减少内存分配开销 |
过度绘制 | 使用clip 限制绘制区域 | 减少GPU填充率负担 |
主线程阻塞 | 复杂计算移至TaskPool | 保持UI线程响应 |