性能问题从哪来
用户对性能的感知很直接:点开慢、滑动卡、切回来要重进。这些问题大多不是算法错,而是主线程被不该在启动时做的事堵住了。优化的第一步不是瞎改,而是先量清楚时间花在哪。
没有度量就没有优化:先 Profiler 找到瓶颈,再动手,别凭感觉。
这篇把鸿蒙应用的性能优化按启动、渲染、内存三块讲清。
启动链路拆解
冷启动从进程创建到首帧上屏,依次经过:应用初始化、Ability 启动、首页构建、首帧渲染。每一段都可能被同步初始化拖慢。原则是:启动路径上只做首屏必需的事,其余延迟到空闲或用户操作时。
onCreate() {
// 只初始化首屏必需
initRouter()
// 非必需的重初始化延后
setTimeout(() => initAnalytics(), 1000)
}
把埋点、预加载这类非首屏任务移出启动关键路径。
首屏渲染优化
首屏慢,常因为一次性构建了太多组件。用懒加载把下面的页面延后构建,首屏只渲染可视区。复杂列表用 LazyForcer 按需生成,而不是一次铺全部。
性能优化清单
- 启动非首屏任务延迟初始化。
- 渲染列表按需生成,避免一次铺全。
- 图片压缩、占位、按需加载。
- 内存及时释放大图与监听。
列表与图片的懒加载
长列表最吃性能。LazyForEach 只渲染滑到的那几项,配合缓存回收。图片要压缩到显示尺寸,别把原图直接塞进小卡片。滑快了还没加载完就给占位图,避免白块闪烁。
内存与泄漏排查
内存泄漏表现为越用越卡、最后被系统杀。常见来源:未注销的全局监听、长生命周期对象持有短生命周期页面。退出页面时把监听、定时器清掉,大图用完即释放。
用 Profiler 定位瓶颈
DevEco Studio 的 Profiler 能看启动时间线、CPU 火焰图、内存曲线。看启动段哪段耗时最长,看火焰图哪个函数占比最高。优化要对着数据来,别凭直觉改一通。
优化前后的度量
每次优化都要记录前后数据:冷启动时长、首帧时间、滑动帧率、内存峰值。没有前后对比,就不知道改动是真有效还是自我安慰。
- 先量基线,再动手。
- 一次只改一处,便于归因。
- 回归验证别引入新卡顿。
实战:把冷启动砍半
典型优化组合:延迟非首屏初始化、首屏列表懒加载、图片压缩。
// 启动时只做路由与首屏数据
onCreate() { initRouter(); loadFirstPage() }
// 埋点与预加载延后
setTimeout(() => { initAnalytics(); prefetchNext() }, 800)
把这三件事做掉,冷启动往往就能明显缩短。性能优化没有银弹,就是把启动关键路径上的每一件非必要的事,一件件挪走。