1# Speeding Up Application Cold Start
2
3Application startup latency is a key factor that affects user experience. When an application is started, the background does not have a process of the application, and therefore the system creates a new process and allocates it to the application. This startup mode is called cold start.
4
5## Analyzing the Time Required for Application Cold Start
6
7The cold start process of applications can be divided into four phases: application process creation and initialization, application and ability initialization, ability/ability stage lifecycle, and home page loading and drawing, as shown below.
8
9![application-cold-start](figures/application-cold-start.png)
10
11## 1. Shortening Time Required for Application Process Creation And Initialization
12
13In the phase of application process creation and initialization, the system creates and initializes an application process, including decoding the icon of the startup page (specified by **startWindowIcon**).
14
15### Using startWindowIcon of Appropriate Resolution
16
17With regard to the icon of the startup page, the recommended maximum resolution is 256 x 256 pixels. Larger resolutions may result in slow startup.
18
19```json
20    "abilities": [
21      {
22        "name": "EntryAbility",
23        "srcEntry": "./ets/entryability/EntryAbility.ets",
24        "description": "$string:EntryAbility_desc",
25        "icon": "$media:icon",
26        "label": "$string:EntryAbility_label",
27        "startWindowIcon": "$media:startIcon", // Modify the icon of the startup page. It is recommended that the icon be less than or equal to 256 x 256 pixels.
28        "startWindowBackground": "$color:start_window_background",
29        "exported": true,
30        "skills": [
31          {
32            "entities": [
33              "entity.system.home"
34            ],
35            "actions": [
36              "action.system.home"
37            ]
38          }
39        ]
40      }
41    ]
42```
43
44The following uses the [SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) tool to compare the startup performance of the startup page icon before optimization (4096 x 4096 pixels) with that after optimization (144 x 144 pixels). The analysis starts when the ability is started (that is, the start point of **H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility**), and ends when **vsync** is received for the first time (that is, the start point of **H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int**).
45
46The comparison data is as follows.
47
48|                        | Start (s)  | End (s)  | Duration (s)|
49| ---------------------- | -------------- | -------------- | ------------ |
50| Before optimization | 5419.484537973 | 5420.327775266 | 0.843237293  |
51| After optimization | 4186.436835246 | 4186.908777335 | 0.471942089  |
52
53As the comparison shows, setting **startWindowIcon** to an icon with an appropriate resolution is effective for shortening the duration of application process creation and initialization.
54
55## 2. Shortening Time Required for Application and Ability Initialization
56
57In the phase of application and ability initialization, resources are loaded, virtual machines are created, application and ability related objects are created and initialized, and dependent modules are loaded.
58
59### Minimizing the Number of Imported Modules
60
61Before executing code, an application must find and load all imported modules. Naturally, each additional third-party framework or module to be loaded by the application increases its startup time. The time required depends on the number and size of the third-party frameworks or modules to load. As such, to speed up startup, use system-provided modules whenever possible and load the modules as required.
62
63The sample code is as follows:
64
65```ts
66// Reduce the number of imported modules.
67// import ability from '@ohos.ability.ability';
68// import dataUriUtils from '@ohos.ability.dataUriUtils';
69// import errorCode from '@ohos.ability.errorCode';
70// import featureAbility from '@ohos.ability.featureAbility';
71// import particleAbility from '@ohos.ability.particleAbility';
72// import wantConstant from '@ohos.ability.wantConstant';
73// import common from '@ohos.app.ability.common';
74// import Configuration from '@ohos.app.ability.Configuration';
75// import contextConstant from '@ohos.app.ability.contextConstant';
76// import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant';
77// import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
78// import GesturePath from '@ohos.accessibility.GesturePath';
79// import GesturePoint from '@ohos.accessibility.GesturePoint';
80// import distributedAccount from '@ohos.account.distributedAccount';
81// import osAccount from '@ohos.account.osAccount';
82
83import AbilityConstant from '@ohos.app.ability.AbilityConstant';
84import UIAbility from '@ohos.app.ability.UIAbility';
85import Want from '@ohos.app.ability.Want';
86import window from '@ohos.window';
87import logger from '../common/Logger';
88
89export default class EntryAbility extends UIAbility {
90  // ...
91}
92```
93
94The following uses the [SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) tool to compare the startup performance before optimization (20 imported modules) with that after optimization (5 imported modules). The analysis starts when the ability is started (that is, the start point of **H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility**), and ends when **vsync** is received for the first time (that is, the start point of **H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int**).
95
96The comparison data is as follows.
97
98|                    | Start (s)  | End (s)  | Duration (s)|
99| ------------------ | -------------- | -------------- | ------------ |
100| Before optimization| 3042.259391282 | 3046.385614613 | 4.126223331  |
101| Before optimization| 4186.436835246 | 4186.908777335 | 0.471942089  |
102
103As the comparison shows, reducing the number of imported modules is effective for shortening the duration of application and ability initialization.
104
105## 3. Shortening Time Required for AbilityStage Lifecycle
106
107In this phase of AbilityStage lifecycle, the AbilityStage lifecycle callbacks are executed.
108
109### Avoiding Time-Consuming Operations in AbilityStage Lifecycle Callbacks
110
111In the application startup process, the system executes the AbilityStage lifecycle callbacks. Whenever possible, avoid performing time-consuming operations in these callbacks. You are advised to perform time-consuming operations through asynchronous tasks or execute them in other threads.
112
113In these lifecycle callbacks, perform only necessary operations. For details, see [AbilityStage Component Container](../application-models/abilitystage.md).
114
115The sample code is as follows:
116
117```ts
118const LARGE_NUMBER = 10000000;
119const DELAYED_TIME = 1000;
120
121export default class MyAbilityStage extends AbilityStage {
122  onCreate(): void {
123    // Time-consuming operation
124    // this.computeTask();
125    this.computeTaskAsync(); // Asynchronous task
126  }
127
128  onAcceptWant(want: Want): string {
129    // Triggered only for the ability with the specified launch type.
130    return 'MyAbilityStage';
131  }
132
133  computeTask(): void {
134    let count = 0;
135    while (count < LARGE_NUMBER) {
136      count++;
137    }
138  }
139
140  private computeTaskAsync(): void {
141    setTimeout(() => {// setTimeout is used to implement asynchronous processing.
142      this.computeTask();
143    }, DELAYED_TIME);
144  }
145}
146```
147
148The following uses the [SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) tool to compare the startup performance before optimization (with synchronous operations) with that after optimization (with asynchronous operations). The analysis starts when the ability is started (that is, the start point of **H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility**), and ends when **vsync** is received for the first time (that is, the start point of **H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int**).
149
150The comparison data is as follows.
151
152|                        | Start (s)  | End (s)  | Duration (s)|
153| ---------------------- | -------------- | -------------- | ------------ |
154| Before optimization| 2124.915558194 | 2127.041354575 | 2.125796381  |
155| After optimization| 4186.436835246 | 4186.908777335 | 0.471942089  |
156
157As the comparison shows, avoiding time-consuming operations in AbilityStage lifecycle callbacks is effective for shortening the time required for the AbilityStage lifecycle.
158
159## 4. Shortening Time Required for Ability Lifecycle
160
161In this phase of ability lifecycle, the ability lifecycle callbacks are executed.
162
163### Avoiding Time-Consuming Operations in Ability Lifecycle Callbacks
164
165In the application startup process, the system executes the ability lifecycle callbacks. Whenever possible, avoid performing time-consuming operations in these callbacks. You are advised to perform time-consuming operations through asynchronous tasks or execute them in other threads.
166
167In these lifecycle callbacks, perform only necessary operations. The following uses the UIAbility as an example. For details about the UIAbility lifecycle, see [UIAbility Lifecycle](../application-models/uiability-lifecycle.md).
168
169```ts
170const LARGE_NUMBER = 10000000;
171const DELAYED_TIME = 1000;
172
173export default class EntryAbility extends UIAbility {
174  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
175    logger.info('Ability onCreate');
176    // Time-consuming operation
177    // this.computeTask();
178    this.computeTaskAsync(); // Asynchronous task
179  }
180
181  onDestroy(): void {
182    logger.info('Ability onDestroy');
183  }
184
185  onWindowStageCreate(windowStage: window.WindowStage): void {
186    logger.info('Ability onWindowStageCreate');
187
188    windowStage.loadContent('pages/Index', (err, data) => {
189      if (err.code) {
190        logger.error('Failed to load the content. Cause: ' + JSON.stringify(err) ?? '');
191        return;
192      }
193      logger.info('Succeeded in loading the content. Data: ' + JSON.stringify(data) ?? '');
194    });
195
196    // Time-consuming operation
197    // this.computeTask();
198    this.computeTaskAsync(); // Asynchronous task
199  }
200
201  onWindowStageDestroy(): void {
202    logger.info('Ability onWindowStageDestroy');
203  }
204
205  onForeground(): void {
206    logger.info('Ability onForeground');
207    // Time-consuming operation
208    // this.computeTask();
209    this.computeTaskAsync(); // Asynchronous task
210  }
211
212  onBackground(): void {
213    logger.info('Ability onBackground');
214  }
215
216  computeTask(): void {
217    let count = 0;
218    while (count < LARGE_NUMBER) {
219      count++;
220    }
221  }
222
223  private computeTaskAsync(): void {
224    setTimeout(() => {// setTimeout is used to implement asynchronous processing.
225      this.computeTask();
226    }, DELAYED_TIME);
227  }
228}
229```
230
231The following uses the [SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) tool to compare the startup performance before optimization (with synchronous operations) with that after optimization (with asynchronous operations). The analysis starts when the ability is started (that is, the start point of **H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility**), and ends when **vsync** is received for the first time (that is, the start point of **H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int**).
232
233The comparison data is as follows.
234
235|                        | Start (s)  | End (s)  | Duration (s)|
236| ---------------------- | -------------- | -------------- | ------------ |
237| Before optimization| 1954.987630036 | 1957.565964504 | 2.578334468  |
238| After optimization| 4186.436835246 | 4186.908777335 | 0.471942089  |
239
240As the comparison shows, avoiding time-consuming operations in ability lifecycle callbacks is effective for shortening the time required for the ability lifecycle.
241
242## 5. Shortening Time Required for Home Page Loading and Drawing
243
244In this phase of home page loading and drawing, the home page content is loaded, the layout is measured, and components are refreshed and drawn.
245
246### Avoid time-consuming operations in the custom component lifecycle callbacks.
247
248When the lifecycle of a custom component changes, the corresponding callback is called.
249
250The **aboutToAppear** function is executed after the custom component instance is created and before the page is drawn. The following code asynchronously processes the time-consuming computing task in **aboutToAppear** to avoid executing the operation in this function and blocking the page drawing.
251
252The sample code is as follows:
253
254```ts
255const LARGE_NUMBER = 10000000;
256const DELAYED_TIME = 1000;
257
258@Entry
259@Component
260struct Index {
261  @State private text: string = "";
262  private count: number = 0;
263
264  aboutToAppear() {
265    // Time-consuming operation
266    // this.computeTask();
267    this.computeTaskAsync(); // Asynchronous task
268    let context = getContext(this) as Context;
269    this.text = context.resourceManager.getStringSync($r('app.string.startup_text'));
270  }
271
272  build() {
273    Column({ space: 10 }) {
274      Text(this.text).fontSize(50)
275    }
276    .width('100%')
277    .height('100%')
278    .padding(10)
279  }
280
281  computeTask(): void {
282    this.count = 0;
283    while (this.count < LARGE_NUMBER) {
284      this.count++;
285    }
286    let context = getContext(this) as Context;
287    this.text = context.resourceManager.getStringSync($r('app.string.task_text'));
288  }
289
290  // Asynchronous processing of the computing task
291  private computeTaskAsync(): void {
292    setTimeout(() => {// setTimeout is used to implement asynchronous processing.
293      this.computeTask();
294    }, DELAYED_TIME);
295  }
296}
297```
298
299The following uses the [SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host) tool to compare the startup performance before optimization (with synchronous operations) with that after optimization (with asynchronous operations). The analysis starts when the ability is started (that is, the start point of **H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility**), and ends when **vsync** is received for the first time (that is, the start point of **H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int**).
300
301The comparison data is as follows.
302
303|                        | Start (s)  | End (s)  | Duration (s)|
304| ---------------------- | -------------- | -------------- | ------------ |
305| Before optimization| 3426.272974492 | 3431.785898837 | 5.512924345  |
306| After optimization| 4186.436835246 | 4186.908777335 | 0.471942089  |
307
308As the comparison shows, avoiding time-consuming operations in custom component lifecycle callbacks is effective for shortening the time required for home page loading and drawing.
309