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 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