• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 提升应用冷启动速度
2
3应用启动时延是影响用户体验的关键要素。当应用启动时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用, 这个启动方式就叫做冷启动。
4
5## 分析应用冷启动耗时
6
7应用冷启动过程大致可分成以下四个阶段:应用进程创建&初始化、Application&Ability初始化、Ability/AbilityStage生命周期、加载绘制首页,如下图:
8
9![输入图片说明](figures/application-cold-start.png)
10
11>**说明:**
12>
13>关于本文中示例,可参考:[提升应用冷启动速度示例](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Ability/Performance/Startup)14
15## 1、缩短应用进程创建&初始化阶段耗时
16
17该阶段主要是系统完成应用进程的创建以及初始化的过程,包含了启动页图标(startWindowIcon)的解码。
18
19### 设置合适分辨率的startWindowIcon
20
21如果启动页图标分辨率过大,解码耗时会影响应用的启动速度,建议启动页图标分辨率不超过256像素*256像素,如下所示:
22
23```json
24    "abilities": [
25      {
26        "name": "EntryAbility",
27        "srcEntry": "./ets/entryability/EntryAbility.ts",
28        "description": "$string:EntryAbility_desc",
29        "icon": "$media:icon",
30        "label": "$string:EntryAbility_label",
31        "startWindowIcon": "$media:startIcon", // 在这里修改启动页图标,建议不要超过256像素x256像素
32        "startWindowBackground": "$color:start_window_background",
33        "exported": true,
34        "skills": [
35          {
36            "entities": [
37              "entity.system.home"
38            ],
39            "actions": [
40              "action.system.home"
41            ]
42          }
43        ]
44      }
45    ]
46```
47
48下面使用[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对使用优化前的启动页图标(4096像素\*4096像素)及使用优化后的启动页图标(144像素\*144像素)的启动性能进行对比分析。分析阶段的起点为启动Ability(即`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(即`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。
49
50对比数据如下:
51
52|                        | 阶段开始(秒)   | 阶段结束(秒)   | 阶段时长(秒) |
53| ---------------------- | -------------- | -------------- | ------------ |
54| 使用优化前的启动页图标 | 5419.484537973 | 5420.327775266 | 0.843237293  |
55| 使用优化后的启动页图标 | 4186.436835246 | 4186.908777335 | 0.471942089  |
56
57可见阶段时长已缩短,故设置合适分辨率的startWindowIcon对缩短应用进程创建&初始化阶段耗时是有效的。
58
59## 2、缩短Application&Ability初始化阶段耗时
60
61该阶段主要是资源加载、虚拟机创建、Application&Ability相关对象的创建与初始化、依赖模块的加载等。
62
63### 减少import的模块
64
65应用代码执行前,应用程序必须找到并加载import的所有模块,应用程序加载的每个额外的第三方框架或者模块都会增加启动时间,耗时长短取决于加载的第三方框架或者模块的数量和大小。推荐开发者尽可能使用系统提供的模块,按需加载,来缩短应用程序的启动耗时。
66
67以下为示例代码:
68
69```ts
70// 优化减少import的模块
71// import ability from '@ohos.ability.ability';
72// import dataUriUtils from '@ohos.ability.dataUriUtils';
73// import errorCode from '@ohos.ability.errorCode';
74// import featureAbility from '@ohos.ability.featureAbility';
75// import particleAbility from '@ohos.ability.particleAbility';
76// import wantConstant from '@ohos.ability.wantConstant';
77// import common from '@ohos.app.ability.common';
78// import Configuration from '@ohos.app.ability.Configuration';
79// import contextConstant from '@ohos.app.ability.contextConstant';
80// import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
81// import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
82// import GesturePath from '@ohos.accessibility.GesturePath';
83// import GesturePoint from '@ohos.accessibility.GesturePoint';
84// import distributedAccount from '@ohos.account.distributedAccount';
85// import osAccount from '@ohos.account.osAccount';
86
87import AbilityConstant from '@ohos.app.ability.AbilityConstant';
88import UIAbility from '@ohos.app.ability.UIAbility';
89import Want from '@ohos.app.ability.Want';
90import window from '@ohos.window';
91import logger from '../common/Logger';
92
93export default class EntryAbility extends UIAbility {
94  // ...
95}
96```
97
98下面使用[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对优化import的模块前(模块数量20个)及优化import的模块后(模块数量5个)的启动性能进行对比分析。分析阶段的起点为启动Ability(即`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(即`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。
99
100对比数据如下:
101
102|                    | 阶段开始(秒)   | 阶段结束(秒)   | 阶段时长(秒) |
103| ------------------ | -------------- | -------------- | ------------ |
104| 优化import的模块前 | 3042.259391282 | 3046.385614613 | 4.126223331  |
105| 优化import的模块后 | 4186.436835246 | 4186.908777335 | 0.471942089  |
106
107可见阶段时长已缩短,故减少import的模块对缩短Application&Ability初始化阶段耗时是有效的。
108
109## 3、缩短AbilityStage生命周期阶段耗时
110
111该阶段主要是AbilityStage的启动生命周期,执行相应的生命周期回调。
112
113### 避免在AbilityStage生命周期回调接口进行耗时操作
114
115在应用启动流程中,系统会执行AbilityStage的生命周期回调函数。因此,不建议在这些回调函数中执行耗时过长的操作,耗时操作建议通过异步任务延迟处理或者放到其他线程执行。
116
117在这些生命周期回调里,推荐开发者只做必要的操作,详情可以参考:[AbilityStage组件容器](../application-models/abilitystage.md)
118
119以下为示例代码:
120
121```ts
122const LARGE_NUMBER = 10000000;
123const DELAYED_TIME = 1000;
124
125export default class MyAbilityStage extends AbilityStage {
126  onCreate(): void {
127    // 耗时操作
128    // this.computeTask();
129    this.computeTaskAsync(); // 异步任务
130  }
131
132  onAcceptWant(want: Want): string {
133    // 仅specified模式下触发
134    return 'MyAbilityStage';
135  }
136
137  computeTask(): void {
138    let count = 0;
139    while (count < LARGE_NUMBER) {
140      count++;
141    }
142  }
143
144  private computeTaskAsync(): void {
145    setTimeout(() => { // 这里使用setTimeout来实现异步延迟运行
146      this.computeTask();
147    }, DELAYED_TIME);
148  }
149}
150```
151
152下面使用[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对优化前同步执行耗时操作及优化后异步执行耗时操作的启动性能进行对比分析。分析阶段的起点为启动Ability(即`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(即`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。
153
154对比数据如下:
155
156|                        | 阶段开始(秒)   | 阶段结束(秒)   | 阶段时长(秒) |
157| ---------------------- | -------------- | -------------- | ------------ |
158| 优化前同步执行耗时操作 | 2124.915558194 | 2127.041354575 | 2.125796381  |
159| 优化后异步执行耗时操作 | 4186.436835246 | 4186.908777335 | 0.471942089  |
160
161可见阶段时长已缩短,故避免在AbilityStage生命周期回调接口进行耗时操作对缩短AbilityStage生命周期阶段耗时是有效的。
162
163## 4、缩短Ability生命周期阶段耗时
164
165该阶段主要是Ability的启动生命周期,执行相应的生命周期回调。
166
167### 避免在Ability生命周期回调接口进行耗时操作
168
169在应用启动流程中,系统会执行Ability的生命周期回调函数。因此,不建议在这些回调函数中执行耗时过长的操作,耗时操作建议通过异步任务延迟处理或者放到其他线程执行。
170
171在这些生命周期回调里,推荐开发者只做必要的操作,下面以UIAbility为例进行说明。关于UIAbility组件生命周期的详细说明,参见[UIAbility组件生命周期](../application-models/uiability-lifecycle.md)。
172
173```ts
174const LARGE_NUMBER = 10000000;
175const DELAYED_TIME = 1000;
176
177export default class EntryAbility extends UIAbility {
178  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
179    logger.info('Ability onCreate');
180    // 耗时操作
181    // this.computeTask();
182    this.computeTaskAsync(); // 异步任务
183  }
184
185  onDestroy(): void {
186    logger.info('Ability onDestroy');
187  }
188
189  onWindowStageCreate(windowStage: window.WindowStage): void {
190    logger.info('Ability onWindowStageCreate');
191
192    windowStage.loadContent('pages/Index', (err, data) => {
193      if (err.code) {
194        logger.error('Failed to load the content. Cause: ' + JSON.stringify(err) ?? '');
195        return;
196      }
197      logger.info('Succeeded in loading the content. Data: ' + JSON.stringify(data) ?? '');
198    });
199
200    // 耗时操作
201    // this.computeTask();
202    this.computeTaskAsync(); // 异步任务
203  }
204
205  onWindowStageDestroy(): void {
206    logger.info('Ability onWindowStageDestroy');
207  }
208
209  onForeground(): void {
210    logger.info('Ability onForeground');
211    // 耗时操作
212    // this.computeTask();
213    this.computeTaskAsync(); // 异步任务
214  }
215
216  onBackground(): void {
217    logger.info('Ability onBackground');
218  }
219
220  computeTask(): void {
221    let count = 0;
222    while (count < LARGE_NUMBER) {
223      count++;
224    }
225  }
226
227  private computeTaskAsync(): void {
228    setTimeout(() => { // 这里使用setTimeout来实现异步延迟运行
229      this.computeTask();
230    }, DELAYED_TIME);
231  }
232}
233```
234
235下面使用[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对优化前同步执行耗时操作及优化后异步执行耗时操作的启动性能进行对比分析。分析阶段的起点为启动Ability(即`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(即`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。
236
237对比数据如下:
238
239|                        | 阶段开始(秒)   | 阶段结束(秒)   | 阶段时长(秒) |
240| ---------------------- | -------------- | -------------- | ------------ |
241| 优化前同步执行耗时操作 | 1954.987630036 | 1957.565964504 | 2.578334468  |
242| 优化后异步执行耗时操作 | 4186.436835246 | 4186.908777335 | 0.471942089  |
243
244可见阶段时长已缩短,故避免在Ability生命周期回调接口进行耗时操作对缩短Ability生命周期阶段耗时是有效的。
245
246## 5、缩短加载绘制首页阶段耗时
247
248该阶段主要是加载首页内容、测量布局、刷新组件并绘制。
249
250### 自定义组件生命周期回调接口里避免耗时操作
251
252自定义组件的生命周期变更会调用相应的回调函数。
253
254aboutToAppear函数会在创建自定义组件实例后,页面绘制之前执行,以下代码在aboutToAppear中对耗时间的计算任务进行了异步处理,避免在该接口执行该耗时操作,不阻塞页面绘制。
255
256以下为示例代码:
257
258```ts
259const LARGE_NUMBER = 10000000;
260const DELAYED_TIME = 1000;
261
262@Entry
263@Component
264struct Index {
265  @State private text: string = "";
266  private count: number = 0;
267
268  aboutToAppear() {
269    // 耗时操作
270    // this.computeTask();
271    this.computeTaskAsync(); // 异步任务
272    let context = getContext(this) as Context;
273    this.text = context.resourceManager.getStringSync($r('app.string.startup_text'));
274  }
275
276  build() {
277    Column({ space: 10 }) {
278      Text(this.text).fontSize(50)
279    }
280    .width('100%')
281    .height('100%')
282    .padding(10)
283  }
284
285  computeTask(): void {
286    this.count = 0;
287    while (this.count < LARGE_NUMBER) {
288      this.count++;
289    }
290    let context = getContext(this) as Context;
291    this.text = context.resourceManager.getStringSync($r('app.string.task_text'));
292  }
293
294  // 运算任务异步处理
295  private computeTaskAsync(): void {
296    setTimeout(() => { // 这里使用setTimeout来实现异步延迟运行
297      this.computeTask();
298    }, DELAYED_TIME);
299  }
300}
301```
302
303下面使用[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对优化前同步执行耗时操作及优化后异步执行耗时操作的启动性能进行对比分析。分析阶段的起点为启动Ability(即`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(即`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。
304
305对比数据如下:
306
307|                        | 阶段开始(秒)   | 阶段结束(秒)   | 阶段时长(秒) |
308| ---------------------- | -------------- | -------------- | ------------ |
309| 优化前同步执行耗时操作 | 3426.272974492 | 3431.785898837 | 5.512924345  |
310| 优化后异步执行耗时操作 | 4186.436835246 | 4186.908777335 | 0.471942089  |
311
312可见阶段时长已缩短,故自定义组件生命周期回调接口里避免耗时操作对缩短加载绘制首页阶段耗时是有效的。