白屏两秒,用户以为你卡死了

你有没有遇到过这种情况:点开应用,先白屏一两秒,然后才出现首页。用户不知道发生了什么,只觉得“这 App 好卡”。更糟的是,有些应用启动时还要转圈,转完才显示内容。

冷启动慢,原因通常不是代码写得烂,而是启动阶段做了太多不该做的事。网络请求、数据库初始化、第三方 SDK 注册、大量同步 IO,全堆在 onWindowStageCreate 里,能不慢吗?

这篇就讲清楚 HarmonyOS 7 的冷启动流程,怎么定位耗时点,怎么用 AppStartup 做任务编排,以及那些你天天在犯的启动错误。

https://placeholder-01.jpg/

一、冷启动到底经历了什么

HarmonyOS 应用的冷启动大致分几个阶段:

  1. 应用进程创建:系统 fork 出应用进程。

  2. AbilityStage 创建:触发 onCreate。

  3. UIAbility 创建:触发 onCreate。

  4. WindowStage 创建:触发 onWindowStageCreate,加载首页。

  5. 首页渲染:ArkUI 构建组件树,上屏。

你写的业务代码,主要集中在 2、3、4 三个阶段。如果这些阶段里有耗时操作,启动就会变慢。

先看一个典型的错误写法:

typescript

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    // 错误:在 onCreate 里做网络请求
    fetchUserInfo();
    // 错误:同步读文件
    const config = fs.readTextSync('/data/config.json');
    // 错误:初始化第三方 SDK
    initAnalytics();
  }

  onWindowStageCreate(windowStage) {
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        console.error('加载首页失败');
      }
    });
  }
}

这些操作每一个都可能花几十到几百毫秒,加起来启动不慢才怪。

二、用埋点找出真正的耗时点

优化之前,先别猜。用 hiTraceMeter 或者简单的 Date.now() 打点,看看每个阶段花了多久。

typescript

import hiTraceMeter from '@ohos.hiTraceMeter';

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    hiTraceMeter.startTrace('ability_onCreate', 1);
    // 业务逻辑
    hiTraceMeter.finishTrace('ability_onCreate', 1);
  }

  onWindowStageCreate(windowStage) {
    hiTraceMeter.startTrace('windowStage_create', 1);
    windowStage.loadContent('pages/Index', (err) => {
      hiTraceMeter.finishTrace('windowStage_create', 1);
    });
  }
}

跑几次,在 DevEco 的 Profiler 里看时间线。你会发现,真正耗时的往往不是框架本身,而是你自己加的初始化逻辑。

https://placeholder-02.png/

三、AppStartup:把启动任务管起来

HarmonyOS 提供了 AppStartup 机制,可以把启动任务拆成一个个 StartupTask,按依赖关系自动编排,还能控制是否在启动阶段执行。

先定义一个启动任务:

typescript

import { StartupTask, StartupTaskContext } from '@ohos.app.appstartup';

export default class InitAnalyticsTask extends StartupTask {
  async init(context: StartupTaskContext): Promise<void> {
    // 初始化埋点 SDK
    await initAnalytics();
  }
}

然后在 module.json5 里配置:

json

{
  "module": {
    "appStartup": {
      "startupTasks": [
        {
          "name": "InitAnalyticsTask",
          "srcEntry": "./ets/startup/InitAnalyticsTask.ets"
        }
      ]
    }
  }
}

AppStartup 的好处是:任务可以并行、可以设置依赖、可以延迟执行。比如你把非首屏必需的初始化都标记为 isOnDemand: true,等首页显示完再执行。

typescript

export default class InitAnalyticsTask extends StartupTask {
  isOnDemand: boolean = true; // 按需执行

  async init(context: StartupTaskContext): Promise<void> {
    await initAnalytics();
  }
}

这样启动阶段只做最关键的事,其他统统往后放。

四、首页渲染优化:别在 build 里做重活

首页本身也要注意。很多人喜欢在 aboutToAppear 里发网络请求,请求回来之前页面是空的,用户看到的就是白屏。

更好的做法是:先渲染骨架屏,数据到了再替换。

typescript

@Entry
@Component
struct Index {
  @State data: string[] = [];
  @State isLoading: boolean = true;

  aboutToAppear() {
    this.loadData();
  }

  async loadData() {
    this.isLoading = true;
    try {
      const result = await fetchData();
      this.data = result;
    } finally {
      this.isLoading = false;
    }
  }

  build() {
    Column() {
      if (this.isLoading) {
        SkeletonList() // 骨架屏组件
      } else {
        List() {
          ForEach(this.data, (item: string) => {
            ListItem() {
              Text(item)
            }
          })
        }
      }
    }
  }
}

骨架屏不用等数据,立刻就能渲染,用户感知上快很多。等数据回来再替换,体验会好很多。

另外,build() 里别做复杂计算。ArkUI 的 build 会频繁执行,你在里面写个循环排序,页面就卡了。所有计算提前在 aboutToAppear 或 onPageShow 里做完。

https://placeholder-03.png/

五、那些年我们踩过的启动坑

坑一:在 onCreate 里同步读文件。

fs.readTextSync 是同步的,文件稍微大一点就阻塞主线程。改成异步:

typescript

const config = await fs.readText('/data/config.json');

坑二:启动时注册大量监听器。

比如网络状态监听、位置监听、传感器监听,这些注册本身不慢,但回调可能频繁触发,影响启动。非必要的监听,等首页显示完再注册。

坑三:第三方 SDK 初始化太重。

很多 SDK 的 init 方法内部会做网络请求、读文件、开线程。如果它不是首屏必需的,用 AppStartup 的 isOnDemand 延迟加载。

坑四:console.log 打太多。

开发阶段随便打,生产环境一定要关掉。大量日志输出会拖慢启动,尤其是循环里打日志。

https://placeholder-04.jpg/

六、总结

这篇讲了 HarmonyOS 7 冷启动的流程、定位方法和优化手段。核心记住三点:

  1. 启动阶段只做最关键的事,其他交给 AppStartup 延迟执行。

  2. 首页先渲染骨架屏,别让用户干等白屏。

  3. 用埋点找耗时点,别凭感觉优化。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐