Skip to content

卡顿检测与优化

鸿蒙卡顿检测:SmartPerf、FPS 监控、主线程耗时检测、线程阻塞分析。


1. 卡顿原理

1.1 VSync 机制

VSync 信号每 16.67ms(60Hz)发送一次

每帧时间线:
├─ 0ms    → VSync 信号
├─ 0-16ms → 应用处理(测量+布局+绘制)
├─ 16ms   → GPU 渲染
└─ 16.67ms → 下一帧 VSync

如果处理时间 > 16.67ms → 掉帧!
如果处理时间 > 33.34ms → 明显卡顿!

1.2 卡顿标准

FPS流畅度说明
≥ 60 FPS流畅正常
30-60 FPS可接受偶发卡顿
10-30 FPS卡顿明显卡顿
< 10 FPS严重卡顿几乎无法用

2. 卡顿检测

2.1 FPS 监控

typescript
import { display } from '@kit.ArkUI'

class FPSMonitor {
    private fps: number = 0
    private frameCount: number = 0
    private lastTime: number = Date.now()

    start(): void {
        this.frameCount = 0
        this.lastTime = Date.now()

        // 每帧回调
        display.getLastDisplay().on('fpsChange', (fps: number) => {
            this.fps = fps

            // FPS < 30 时告警
            if (fps < 30) {
                console.warn(`FPS 过低: ${fps}`)
                this.reportLag(fps)
            }

            // FPS < 10 时严重告警
            if (fps < 10) {
                console.error(`严重卡顿: ${fps}`)
            }
        })
    }

    private reportLag(fps: number): void {
        // 上报卡顿信息到监控系统
        // this.uploadLagData(fps, this.getCurrentStack())
    }
}

// 使用
let fpsMonitor = new FPSMonitor()
fpsMonitor.start()

2.2 主线程耗时检测

typescript
// 检测主线程耗时操作
function checkMainThread(name: string, callback: () => void): void {
    let start = performance.now()
    callback()
    let duration = performance.now() - start

    if (duration > 10) {
        console.warn(`${name} 主线程耗时: ${duration}ms`)
    }
}

// 使用
checkMainThread('列表渲染', () => {
    // 渲染逻辑
})

3. 卡顿优化

3.1 避免主线程阻塞

typescript
// ❌ 错误:主线程执行耗时操作
@Entry
@Component
struct BadPage {
    aboutToAppear() {
        // 阻塞主线程!
        this.loadData()
        this.processImages()
    }
}

// ✅ 正确:异步处理
@Entry
@Component
struct GoodPage {
    aboutToAppear() {
        // 主线程只做 UI 初始化
        this.initUI()

        // 耗时操作放后台
        TaskPool.execute(() => {
            let data = this.loadData()
            let images = this.processImages()

            // 回到主线程更新 UI
            context.getMainContext().syncDispatch(() => {
                this.data = data
                this.images = images
            })
        })
    }
}

3.2 复杂布局优化

布局复杂度 vs 性能:

✅ 扁平布局(推荐):
Column() {
    Row() {
        Image()
        Text()
    }
    List()  // 使用 LazyForEach
}

❌ 嵌套布局(避免):
Column() {
    Column() {
        Row() {
            Column() {
                Row() {
                    Text()
                    Text()
                }
                Text()
            }
        }
    }
}
// 嵌套 > 10 层时性能明显下降

4. SmartPerf 工具

4.1 SmartPerf 功能

SmartPerf(性能分析工具):
├─ FPS 监控(实时/离线)
├─ 帧耗时分析(每帧各阶段耗时)
├─ CPU 频率监控
├─ 内存分配监控
├─ 网络请求耗时分析
└─ 卡顿自动检测与上报

4.2 使用方法

typescript
import { smartPerf } from '@kit.SmartPerfKit'

// 开启 FPS 监控
smartPerf.start()

// 开始分析
smartPerf.startTrace('app_trace')

// 结束分析
smartPerf.stopTrace('app_trace')
    .then((result: string) => {
        // 获取性能报告
        console.log('性能报告:', result)
    })

// 上报卡顿
smartPerf.reportLag({
    fps: this.fps,
    duration: this.frameDuration,
    stack: this.getCurrentStack()
})

5. 面试高频考点

Q1: 卡顿的根源?

回答:主线程执行耗时操作(网络、I/O、复杂计算、布局嵌套过深),导致无法在 16.67ms 内完成一帧。

Q2: 如何检测和修复卡顿?

回答:SmartPerf/FPS 监控发现卡顿 → 查看帧耗时分析定位瓶颈 → 主线程异步化、布局扁平化、图片懒加载。


🐱 小猫提示:卡顿优化记住 "FPS≥60、主线程异步化、布局扁平化、SmartPerf 检测、避免嵌套"