# æå‡åº”用冷å¯åŠ¨é€Ÿåº¦ 应用å¯åŠ¨æ—¶å»¶æ˜¯å½±å“用户体验的关键è¦ç´ 。当应用å¯åŠ¨æ—¶ï¼ŒåŽå°æ²¡æœ‰è¯¥åº”ç”¨çš„è¿›ç¨‹ï¼Œè¿™æ—¶ç³»ç»Ÿä¼šé‡æ–°åˆ›å»ºä¸€ä¸ªæ–°çš„进程分é…给该应用, 这个å¯åŠ¨æ–¹å¼å°±å«åšå†·å¯åŠ¨ã€‚ ## 分æžåº”用冷å¯åŠ¨è€—æ—¶ 应用冷å¯åŠ¨è¿‡ç¨‹å¤§è‡´å¯åˆ†æˆä»¥ä¸‹äº”个阶段:应用进程创建&åˆå§‹åŒ–ã€Application&Abilityåˆå§‹åŒ–ã€Ability/AbilityStage生命周期ã€åŠ è½½ç»˜åˆ¶é¦–é¡µã€ç½‘络数æ®äºŒæ¬¡åˆ·æ–°ï¼Œå¦‚下图:  1. **应用进程创建&åˆå§‹åŒ–阶段**ï¼šè¯¥é˜¶æ®µä¸»è¦æ˜¯ç³»ç»Ÿå®Œæˆåº”用进程的创建以åŠåˆå§‹åŒ–的过程,包å«äº†å¯åŠ¨é¡µå›¾æ ‡(startWindowIcon)的解ç 。 2. **Application&Abilityåˆå§‹åŒ–**ï¼šè¯¥é˜¶æ®µä¸»è¦æ˜¯èµ„æºåŠ è½½ã€è™šæ‹Ÿæœºåˆ›å»ºã€Application&Ability相关对象的创建与åˆå§‹åŒ–ã€ä¾èµ–模å—çš„åŠ è½½ç‰ã€‚ 3. **Ability/AbilityStage生命周期**ï¼šè¯¥é˜¶æ®µä¸»è¦æ˜¯AbilityStage/Abilityçš„å¯åŠ¨ç”Ÿå‘½å‘¨æœŸï¼Œæ‰§è¡Œç›¸åº”çš„ç”Ÿå‘½å‘¨æœŸå›žè°ƒã€‚ 4. **åŠ è½½ç»˜åˆ¶é¦–é¡µ**ï¼šè¯¥é˜¶æ®µä¸»è¦æ˜¯åŠ è½½é¦–é¡µå†…å®¹ã€æµ‹é‡å¸ƒå±€ã€åˆ·æ–°ç»„件并绘制。 5. **网络数æ®äºŒæ¬¡åˆ·æ–°**ï¼šè¯¥é˜¶æ®µä¸»è¦æ˜¯åº”ç”¨æ ¹æ®ä¸šåŠ¡éœ€è¦å¯¹ç½‘络数æ®è¿›è¡Œè¯·æ±‚ã€å¤„ç†ã€äºŒæ¬¡åˆ·æ–°ã€‚ å¯è§å¦‚æžœæƒ³è¦æå‡åº”用冷å¯åŠ¨é€Ÿåº¦ï¼Œéœ€è¦ç¼©çŸä»¥ä¸Šå‡ 个阶段的耗时。 >**说明:** > > 1. 关于本文ä¸ç¤ºä¾‹ï¼Œå¯å‚考:[æå‡åº”用冷å¯åŠ¨é€Ÿåº¦ç¤ºä¾‹](https://gitee.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Ability/Performance/Startup)。 > 2. 如何使用SmartPerf工具分æžå†·å¯åЍå¯å‚考:[应用冷å¯åŠ¨åˆ†æž](performance-optimization-using-smartperf-host.md#应用冷å¯åŠ¨åˆ†æž)。 ## 1ã€ç¼©çŸåº”用进程创建&åˆå§‹åŒ–阶段耗时 è¯¥é˜¶æ®µä¸»è¦æ˜¯ç³»ç»Ÿå®Œæˆåº”用进程的创建以åŠåˆå§‹åŒ–的过程,包å«äº†å¯åŠ¨é¡µå›¾æ ‡(startWindowIcon)的解ç 。 ### 设置åˆé€‚分辨率的startWindowIcon 该优化场景仅支æŒrk3568开呿¿ã€‚如果å¯åŠ¨é¡µå›¾æ ‡åˆ†è¾¨çŽ‡è¿‡å¤§ï¼Œè§£ç 耗时会影å“应用的å¯åŠ¨é€Ÿåº¦ï¼Œå»ºè®®å¯åŠ¨é¡µå›¾æ ‡åˆ†è¾¨çŽ‡ä¸è¶…过256åƒç´ *256åƒç´ ,如下所示: ```json "abilities": [ { "name": "EntryAbility", "srcEntry": "./ets/entryability/EntryAbility.ets", "description": "$string:EntryAbility_desc", "icon": "$media:icon", "label": "$string:EntryAbility_label", "startWindowIcon": "$media:startIcon", // 在这里修改å¯åŠ¨é¡µå›¾æ ‡ï¼Œå»ºè®®ä¸è¦è¶…过256åƒç´ x256åƒç´ "startWindowBackground": "$color:start_window_background", "exported": true, "skills": [ { "entities": [ "entity.system.home" ], "actions": [ "action.system.home" ] } ] } ] ``` 下é¢ä½¿ç”¨[SmartPerf](https://gitee.com/openharmony/developtools_smartperf_host)工具,对使用优化å‰çš„å¯åŠ¨é¡µå›¾æ ‡ï¼ˆ4096åƒç´ \*4096åƒç´ )åŠä½¿ç”¨ä¼˜åŒ–åŽçš„å¯åŠ¨é¡µå›¾æ ‡ï¼ˆ144åƒç´ \*144åƒç´ )的å¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžã€‚分æžé˜¶æ®µçš„èµ·ç‚¹ä¸ºç‚¹å‡»åº”ç”¨å›¾æ ‡æ‰“å¼€åº”ç”¨æ—¶è§¦å‘的触摸事件(å³`ProcessTouchEvent`的结æŸç‚¹ï¼‰ï¼Œé˜¶æ®µç»ˆç‚¹ä¸ºåº”用第一次接到vsync(å³`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。 对比数æ®å¦‚下(性能耗时数æ®å› 设备版本而异,以实测为准): | 方案 | 阶段时长(毫秒) | |-------------|:--------:| | 使用优化å‰çš„å¯åŠ¨é¡µå›¾æ ‡ | 998.6 | | 使用优化åŽçš„å¯åŠ¨é¡µå›¾æ ‡ | 722.5 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œæ•…设置åˆé€‚分辨率的startWindowIcon对缩çŸåº”用进程创建&åˆå§‹åŒ–阶段耗时是有效的。 ## 2ã€ç¼©çŸApplication&Abilityåˆå§‹åŒ–阶段耗时 è¯¥é˜¶æ®µä¸»è¦æ˜¯èµ„æºåŠ è½½ã€è™šæ‹Ÿæœºåˆ›å»ºã€Application&Ability相关对象的创建与åˆå§‹åŒ–ã€ä¾èµ–模å—çš„åŠ è½½ç‰ã€‚ 主è¦è€—时点在于资æºåŠ è½½é˜¶æ®µï¼Œåˆ†ä¸ºä¸»è¦çš„三个æ¥éª¤ï¼šæ–‡ä»¶åŠ è½½ã€ä¾èµ–模å—è§£æžã€æ–‡ä»¶æ‰§è¡Œã€‚ 1. æ–‡ä»¶åŠ è½½ï¼šæŸ¥æ‰¾å¹¶è§£æžæ‰€æœ‰çš„æ–‡ä»¶åˆ°æ¨¡å—ä¸è®°å½•。 2. ä¾èµ–模å—è§£æžï¼ˆå®žä¾‹åŒ–):分é…内å˜ç©ºé—´æ¥å˜æ”¾æ¨¡å—所有导出的å˜é‡ï¼Œä½†è¿™æ—¶å€™å†…å˜ä¸å¹¶æ²¡æœ‰åˆ†é…å˜é‡çš„值。 3. 文件执行:è¿è¡Œets文件,将内å˜ä¸ä¹‹å‰æœªåˆ†é…值的å˜é‡èµ‹ä¸ºçœŸå®žçš„值。 下é¢å°†é’ˆå¯¹è¿™ä¸‰ä¸ªé˜¶æ®µå¯èƒ½å˜åœ¨çš„优化手段进行详细展开说明。 ### å‡å°‘使用嵌套export *的方å¼å…¨é‡å¯¼å‡º 应用冷å¯åŠ¨è¿‡ç¨‹ä¸ï¼Œä¼šåœ¨**HandleLaunchAbility**䏿‰§è¡Œå†·å¯åŠ¨ç›¸å…³.ets文件,所有被主页é¢importçš„.ets文件å‡ä¼šè¢«æ‰§è¡Œï¼ŒåŒ…括数æ®ç»“æž„ã€å˜é‡ã€å…¨å±€å‡½æ•°çš„åˆå§‹åŒ–ç‰ã€‚首页需è¦ç”¨åˆ°çš„å˜é‡åŠå‡½æ•°ç‰å¯èƒ½æ¥æºäºŽå…¶ä»–ets文件,通过exportçš„å½¢å¼æä¾›ç»™é¦–é¡µä½¿ç”¨ã€‚ 例:Numbers文件导出`export One`,需è¦åœ¨MainPage.etsä¸ä½¿ç”¨ï¼Œå°½é‡ç›´æŽ¥å¯¼å…¥æˆ–者åªåµŒå¥—一层Index文件,å³åœ¨MainPage.etsä¸ç›´æŽ¥`import { One } from './Numbers'`。é¿å…在Utils文件`export * from './Numbers'`,在SecondPageæ–‡ä»¶å†æ¬¡`export * from './Utils'`,最åŽåœ¨A文件ä¸`import * from './SecondPage'`。 以下为示例代ç : ã€ä¼˜åŒ–å‰ã€‘å˜åœ¨å¤šå±‚嵌套export *的方å¼å…¨é‡å¯¼å‡º ```ts // Numbers.ets export const One: number = 1; // ... // æ¤å¤„嵌套多层export * // Utils.ets export * from './Numbers'; // SecondPage.ets export * from './Utils'; // Index.ets import * from './SecondPage'; ``` ã€ä¼˜åŒ–åŽã€‘ä¸å˜åœ¨åµŒå¥—export *ï¼Œä»Žç›®æ ‡æ–‡ä»¶ä¸ç›´æŽ¥import ```ts // 去掉冗余嵌套的export,å³åœ¨Index.etsä¸ç›´æŽ¥import { One } from './Numbers'。 // Numbers.ets export const One: number = 1; // Index.ets import { One } from './Numbers'; ``` 由于ä¾èµ–模å—è§£æžé‡‡ç”¨æ·±åº¦ä¼˜å…ˆéåŽ†çš„æ–¹å¼æ¥é历模å—ä¾èµ–å…³ç³»å›¾ä¸æ¯ä¸€ä¸ªæ¨¡å—è®°å½•ï¼Œä¼šå…ˆä»Žå…¥å£æ–‡ä»¶çš„第一个导入è¯å¥å¼€å§‹ä¸€å±‚层往更深层查找,直到最åŽä¸€ä¸ªæ²¡æœ‰å¯¼å…¥è¯å¥çš„æ¨¡å—为æ¢ï¼Œè¿žæŽ¥å¥½è¿™ä¸ªæ¨¡å—的导出å˜é‡ä¹‹åŽä¼šå›žåˆ°ä¸Šä¸€çº§çš„æ¨¡å—ç»§ç»è¿™ä¸ªæ¥éª¤ï¼Œå› æ¤å¤šå±‚export *的使用会导致ä¾èµ–模å—è§£æžã€æ–‡ä»¶æ‰§è¡Œé˜¶æ®µè€—时增长。 针对上述示例代ç 关注该阶段耗时差异,对优化å‰åŽå¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžã€‚分æžé˜¶æ®µçš„èµ·ç‚¹ä¸ºå¼€å§‹åŠ è½½abc文件(å³`H:JSPandaFileExecutor::ExecuteFromAbcFile`),阶段终点为`abc文件`åŠ è½½å®Œæˆã€‚ ã€ä¼˜åŒ–å‰ã€‘å˜åœ¨8层嵌套export *  ã€ä¼˜åŒ–åŽã€‘ä¸å˜åœ¨åµŒå¥—export *ï¼Œä»Žç›®æ ‡æ–‡ä»¶ä¸ç›´æŽ¥import  对比数æ®å¦‚下: | 方案 | 阶段时长(微秒) | |-------------|:----------:| | (优化å‰ï¼‰å˜åœ¨8层嵌套export * | 492.6 | | (优化åŽï¼‰ä¸å˜åœ¨åµŒå¥—export *ï¼Œä»Žç›®æ ‡æ–‡ä»¶ä¸ç›´æŽ¥import | 388.7 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸã€‚å› æ¤å‡å°‘多层文件的嵌套导出export *å¯ä»¥æå‡åº”用冷å¯åŠ¨é€Ÿåº¦ã€‚ >**说明:** > >本示例ä¸åµŒå¥—å±‚æ¬¡è¾ƒæµ…ï¼Œä»Žæ—¶é—´ä¸Šè§‚æµ‹åˆ°çš„æ”¶ç›Šä¸æ˜Žæ˜¾ï¼Œå½“实际开å‘过程ä¸å¯èƒ½ä¼šæ¶‰åŠåˆ°æ›´åР夿‚的情况,修改åŽå¯¹æ€§èƒ½æ”¶ç›Šä¼šæ›´æ˜Žæ˜¾ã€‚ ### å‡å°‘import *的方å¼å…¨é‡å¼•用 应用程åºåŠ è½½è¿‡ç¨‹ä¸ï¼Œéœ€è¦ä½¿ç”¨ä¸åŒæ¨¡å—ä¸çš„å˜é‡æˆ–函数,通常应用开å‘者会将相åŒç±»åž‹çš„å˜é‡æˆ–函数放在åŒä¸€ä¸ªå·¥å…·ç±»æ–‡ä»¶å½“ä¸ï¼Œä½¿ç”¨æ—¶é€šè¿‡import的方å¼å¼•入对应的模å—,当工具类ä¸å˜åœ¨è¾ƒå¤šæš´éœ²å‡½æ•°æˆ–å˜é‡æ—¶ï¼ŒæŽ¨è直接import对应的å˜é‡ï¼Œå¯ä»¥å‡å°‘该阶段ä¸.ets文件执行耗时,å³å‡å°‘æ–‡ä»¶ä¸æ‰€æœ‰exportå˜é‡çš„åˆå§‹åŒ–过程。 以下为示例代ç : ã€ä¼˜åŒ–å‰ã€‘Index.etsä¸ä½¿ç”¨ import * as nm from '../utils/Numbers'。 ```ts // Index.ets import * as nm from '../utils/Numbers'; // 䏿ލèimport *çš„æ–¹å¼ hilog.info(0x0000, 'testTag', '%{public}d', nm.One); // æ¤å¤„仅用到å˜é‡One // Numbers.ets export const One: number = 1; export const Two: number = 2; // ... // æ¤å¤„çœç•¥2000æ¡æ•°æ® ``` ã€ä¼˜åŒ–åŽã€‘Index.etsä¸ä½¿ç”¨ import { One } from '../utils/Numbers'。 ```ts // Index.ets import { One } as nm from '../utils/Numbers'; // æŽ¨èæŒ‰éœ€å¼•用å˜é‡ hilog.info(0x0000, 'testTag', '%{public}d', One); // æ¤å¤„仅用到å˜é‡One // Numbers.ets export const One: number = 1; export const Two: number = 2; // ... // æ¤å¤„çœç•¥2000æ¡æ•°æ® ``` 下é¢å¯¹ä¼˜åŒ–å‰åŽå¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžï¼Œåˆ†æžé˜¶æ®µçš„起点为UI Ability Launching开始(å³`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility(const std::shared_ptr<AbilityLocalRecord> &`)的开始点),阶段终点为UI Ability Launching结æŸï¼ˆå³`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility(const std::shared_ptr<AbilityLocalRecord> &)`的结æŸç‚¹ï¼‰ã€‚ ã€ä¼˜åŒ–å‰ã€‘使用import * as nmå…¨é‡å¼•用2000æ¡æ•°æ®  ã€ä¼˜åŒ–åŽã€‘使用import { One }按需引用  对比数æ®å¦‚下: | 方案 | 阶段时长(毫秒) | |-------------|:-------------:| | (优化å‰ï¼‰ä½¿ç”¨import * as nmå…¨é‡å¼•用 | 16.7 | | (优化åŽï¼‰ä½¿ç”¨import { One }按需引用 | 7.1 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸã€‚å› æ¤å°†éžUI耗时æ“作移至å线程ä¸å¤„ç†ï¼Œå¯ä»¥ç¼©çŸåº”用冷å¯åŠ¨å®Œæˆæ—¶å»¶ã€‚ >**说明:** > > **æ¤ä¼˜åŒ–方案仅å¯å°†å†·å¯åŠ¨é˜¶æ®µè€—æ—¶ç¼©çŸï¼Œä½†æ˜¯å¯èƒ½å¯¼è‡´å…¶ä»–场景耗时增长,å³å˜é‡åˆå§‹åŒ–过程从冷å¯åŠ¨é˜¶æ®µåˆ†æ‘Šè‡³å…¶ä»–ä½¿ç”¨é˜¶æ®µ**。 > 例:二级页é¢ä½¿ç”¨åˆ°Numberä¸Twoå˜é‡ï¼Œæ¤æ–¹æ¡ˆä¼šä½¿äºŒçº§é¡µé¢è·³è½¬è¿‡ç¨‹å¯¹æ¯”优化å‰è€—时更长。 ### å‡å°‘使用未引用的importæ¨¡å— åº”ç”¨ä»£ç æ‰§è¡Œå‰ï¼Œåº”用程åºå¿…é¡»æ‰¾åˆ°å¹¶åŠ è½½import的所有模å—。应用程åºå¯åŠ¨æ—¶ä¼šå› åŠ è½½å¹¶ä½¿ç”¨çš„æ¯ä¸ªé¢å¤–第三方框架或模å—è€Œå¢žåŠ å¯åŠ¨è€—æ—¶ï¼Œè€—æ—¶é•¿çŸå–å†³äºŽåŠ è½½çš„ç¬¬ä¸‰æ–¹æ¡†æž¶æˆ–è€…æ¨¡å—的数é‡å’Œå¤§å°ã€‚推èå¼€å‘者尽å¯èƒ½ä½¿ç”¨ç³»ç»Ÿæä¾›çš„æ¨¡å—ï¼ŒæŒ‰éœ€åŠ è½½ï¼Œæ¥ç¼©çŸåº”用程åºçš„å¯åŠ¨è€—æ—¶ã€‚ 以下为示例代ç : ```ts // 优化å‡å°‘importçš„æ¨¡å— // import { particleAbility, featureAbility, wantConstant } from '@kit.AbilityKit'; // import { FormExtensionAbility } from '@kit.FormKit'; // import { GesturePath, GesturePoint } from '@kit.AccessibilityKit'; // import { distributedAccount, BusinessError, osAccount } from '@kit.BasicServicesKit'; // import { webview } from '@kit.ArkWeb'; import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; import { window } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // ... // webview.WebviewController.initializeWebEngine(); } // ... } ``` 需è¦è¯´æ˜Žï¼Œè¿™é‡Œä¸ºäº†æ–¹ä¾¿å¯¹æ¯”该阶段导入模å—å’Œä¸å¯¼å…¥æ¨¡å—的性能差异,用一个@ohos.web.webview模å—进行对比,这里å‡è®¾@ohos.web.webview模å—å¹¶éžè¯¥é˜¶æ®µå¿…须导入的模å—。而在实际业务场景ä¸ï¼Œç”±äºŽwebviewåˆå§‹åŒ–时间较长,如果放到页é¢è·³è½¬æ—¶å†å¯¼å…¥è¯¥æ¨¡å—进行使用,有å¯èƒ½ä¼šåŠ£åŒ–é¡µé¢è·³è½¬çš„å®Œæˆæ—¶å»¶ã€‚å› æ¤ï¼Œæ¨¡å—是å¦èƒ½åœ¨è¯¥é˜¶æ®µè¿›è¡Œä¼˜åŒ–还需è¦ç»“åˆå…·ä½“业务场景进行评估。 下é¢ä½¿ç”¨DevEco Studio内置的Profilerä¸çš„å¯åŠ¨åˆ†æžå·¥å…·Launch,对优化import的模å—å‰ï¼ˆå¯¼å…¥@ohos.web.webview模å—)åŠä¼˜åŒ–import的模å—åŽï¼ˆä¸å¯¼å…¥@ohos.web.webview模å—)的å¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžã€‚䏋颿˜¯Launch工具抓å–çš„UI Ability Launchingï¼ˆåŠ è½½UI Ability)耗时,对比数æ®å¦‚下(性能耗时数æ®å› 设备型å·ç‰ˆæœ¬è€Œå¼‚,以实测为准): | 方案 | UI Ability Launching阶段时长(毫秒) | |--------------|:----------------------------:| | 优化import的模å—å‰ | 26 | | 优化import的模å—åŽ | 10 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œæ•…å‡å°‘import的模å—对缩çŸApplication&Abilityåˆå§‹åŒ–阶段耗时是有效的。这里建议该阶段应å‡å°‘应用å¯åŠ¨æ—¶éžå¿…è¦çš„import模å—ï¼ŒæŒ‰éœ€åŠ è½½æ¨¡å—,缩çŸåº”用程åºçš„å¯åŠ¨è€—æ—¶ã€‚ ### åˆç†æ‹†åˆ†å¯¼å‡ºæ–‡ä»¶ï¼Œå‡å°‘冗余文件执行 应用程åºåŠ è½½æ¨¡å—åŽï¼Œéœ€è¦æ‰§è¡Œåº”用侧的.ets文件,对其进行åˆå§‹åŒ–,并执行全局åˆå§‹åŒ–å˜é‡ã€å‡½æ•°ã€‚å¯ä»¥å°†æ–‡ä»¶åˆ†ä¸ºä¸¤ç±»ï¼Œä¸€ç±»ä¸ºå†·å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶ï¼ˆå¦‚é¦–é¡µå±•ç¤ºç•Œé¢åŠç»„件相关文件),一类为éžå†·å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶ï¼ˆå¦‚è·³è½¬åŽäºŒçº§é¡µé¢ï¼‰ï¼Œåœ¨å†·å¯åŠ¨è¿‡ç¨‹ä¸ä»…执行冷å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶ï¼Œæ¥ç¼©çŸåº”用的å¯åŠ¨è€—æ—¶ã€‚ **场景示例:** 应用å˜åœ¨ä¸¤ä¸ªé¡µé¢ï¼Œé¦–页Index展示为HAR包ä¸**MainPage.ets**çš„Text组件,该文件ä¸ä¸åŒ…å«è€—æ—¶æ“作;首页点击Text跳转至**SecondPage**,其ä¸å¼•用了HAR包ä¸çš„**SubPage.ets**,该文件å˜åœ¨å…¨å±€å‡½æ•°çš„耗时æ“作,会在模å—åŠ è½½æ—¶æ‰§è¡Œã€‚ä½†æ˜¯HAR包ä¸çš„导出文件Index.etsåŒæ—¶å¯¼å‡ºäº†**MainPage.etså’ŒSubPage.ets**,而首页直接import { MainPage } from 'library/Index'的方å¼ä¼šå¯¼è‡´åº”用在冷å¯åŠ¨è¿‡ç¨‹ä¸æ‰§è¡Œäº†éžå†·å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶**SubPage.ets**ï¼Œå¢žåŠ äº†å†·å¯åŠ¨è€—æ—¶ã€‚ ã€ä¼˜åŒ–å‰ã€‘åŠ è½½æ¨¡å—æ—¶æ‰§è¡Œäº†éžå†·å¯åŠ¨ç›¸å…³æ–‡ä»¶SubPage.ets  以下为示例代ç : ```ts // entry/src/main/ets/pages/Index.ets import { MainPage } from 'library/Index'; // 䏿ލè用法:直接导入了与冷å¯åЍéžå¼ºç›¸å…³æ–‡ä»¶SubPage.ets export struct Index{ @Provide pathStack: NavPathStack = new NavPathStack(); build() { Navigation(this.pathStack) { Row() { // 引用HAR的自定义组件 MainPage() } } } } // library/src/main/ets/components/mainpage/MainPage.ets @Component export struct MainPage { @Consume pathStack: NavPathStack; @State message: string = 'HAR MainPage'; build() { Row() { Text(this.message) .fontSize(32) .fontWeight(FontWeight.Bold) }.onClick(() => { this.pathStack.pushPath({ name: 'SecondPage' }); }) } } // entry/src/main/ets/pages/SecondPage.ets import { SubPage } from 'library/Index'; @Builder export function SecondPageBuilder() { SecondPage() } @Entry @Component struct SecondPage { pathStack: NavPathStack = new NavPathStack(); build() { NavDestination() { Row() { // 引用HAR的自定义组件 SubPage() } .height('100%') } .onReady((context: NavDestinationContext) => { this.pathStack = context.pathStack; }) } } // library/src/main/ets/components/mainpage/SubPage.ets // SubPageä¸çš„全局耗时函数 const LARGE_NUMBER = 10000000; function computeTask(): number { let count = 0; while (count < LARGE_NUMBER) { count++; } return count; } let count = computeTask(); // ... // library/Index.ets export { MainPage } from './src/main/ets/components/mainpage/MainPage'; // 冷å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶ export { SubPage } from './src/main/ets/components/mainpage/SubPage'; // éžå†·å¯åŠ¨å¼ºç›¸å…³æ–‡ä»¶ ``` **ã€ä¼˜åŒ–方案一】** å°†HAR包的导出文件**Index.ets**进行拆分,**IndexAppStart.ets**文件仅导出首页相关文件,å³**MainPage.ets**。**IndexOthers.ets**文件导出éžé¦–页相关文件,å³**SubPage.ets。** **优点**:使用æ¤ç§æ–¹æ¡ˆä¼˜åŒ–åŽå¯ä»¥å°†å†·å¯é˜¶æ®µï¼ˆåŠ è½½é¦–é¡µæ–‡ä»¶ï¼‰ä¸Žéžå†·å¯é˜¶æ®µï¼ˆåŠ è½½éžé¦–é¡µæ–‡ä»¶ï¼‰éœ€è¦æ‰§è¡Œçš„.ets文件进行完全拆分,类比其他需优化的场景也å¯ä»¥ä½¿ç”¨æœ¬æ–¹æ¡ˆè¿›è¡Œæ‹†åˆ†ã€‚ **缺点**:需ä¿è¯æ‹†åˆ†åŽIndexAppStart.etsä¸çš„导出文件ä¸å˜åœ¨å¯¹äºŽIndexOthers.etsä¸çš„导出文件的引用。 ã€å›¾ä¸€ã€‘拆分HAR导出文件  以下为示例代ç : 1. å°†HAR包的导出文件Index.ets进行拆分,IndexAppStart.ets文件仅导出首页相关文件,IndexOthers.ets文件导出éžé¦–页相关文件。 ```ts // library/IndexAppStart.ets export { MainPage } from './src/main/ets/components/mainpage/MainPage'; // library/IndexOthers.ets export { SubPage } from './src/main/ets/components/mainpage/SubPage'; ``` 2. 首页Index从IndexAppStart.ets导入MainPage。 ```ts // Index.ets import { MainPage } from 'library/IndexAppStart'; @Entry @Component struct Index { @Provide pathStack: NavPathStack = new NavPathStack(); build() { Navigation(this.pathStack) { Row() { // 引用HAR的自定义组件 MainPage() } } .height('100%') .width('100%') } } ``` 3. 跳转åŽçš„页é¢SecondPage从IndexOthers.ets导入SubPage。 ```ts // SecondPage.ets import { SubPage } from 'library/IndexOthers'; @Builder export function SecondPageBuilder() { SecondPage() } @Entry @Component struct SecondPage { pathStack: NavPathStack = new NavPathStack(); build() { NavDestination() { Row() { // 引用HAR的自定义组件 SubPage() } .height('100%') } .onReady((context: NavDestinationContext) => { this.pathStack = context.pathStack; }) } } ``` **ã€ä¼˜åŒ–方案二】** 在首页的**Index.ets**文件ä¸å¯¼å…¥**MainPage.ets**时使用全路径展开。 **优点**:ä¸éœ€è¦æ–°å¢žæ–‡ä»¶æ¥æ±‡æ€»å¯¼å‡ºæ‰€æœ‰å†·å¯é˜¶æ®µæ–‡ä»¶ã€‚ **缺点**:引用时需è¦å¯¹æ‰€æœ‰å†·å¯é˜¶æ®µæ–‡ä»¶è¿›è¡Œè·¯å¾„å±•å¼€ï¼Œå¢žåŠ å¼€å‘å’Œç»´æŠ¤æˆæœ¬ã€‚ ã€å›¾äºŒã€‘首页导入冷å¯åŠ¨æ–‡ä»¶æ—¶ä½¿ç”¨å…¨è·¯å¾„å±•å¼€  以下为示例代ç : ```ts // Index.ets import { MainPage } from 'library/src/main/ets/components/mainpage/MainPage'; @Entry @Component struct Index { @Provide pathStack: NavPathStack = new NavPathStack(); build() { Navigation(this.pathStack) { Row() { // 引用HAR的自定义组件 MainPage() } } .height('100%') .width('100%') } } ``` >**说明:** > >1. **上述两ç§ä¼˜åŒ–方案默认MainPageä¸ä¸å˜åœ¨å¯¹äºŽSubPageä¸çš„import。** >2. **当å˜åœ¨MainPage对于SubPage的直接import时,需è¦ä½¿ç”¨[动æ€import](../arkts-utils/arkts-dynamic-import.md)方法æ¥è¿›è¡Œä¼˜åŒ–。** >3. å¼€å‘者å¯è‡ªè¡Œæ ¹æ®ä¼˜åŒ–方案的优缺点æƒè¡¡é€‰æ‹©åˆé€‚的优化方案。 下é¢å¯¹ä¼˜åŒ–å‰åŽå¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžã€‚阶段起点为`UI Ability Launching`的开始点,阶段终点为应用首帧å³`First Frame - App Phase`的开始点。 ã€ä¼˜åŒ–å‰ã€‘åŠ è½½æ¨¡å—æ—¶æ‰§è¡Œäº†éžå†·å¯åŠ¨ç›¸å…³æ–‡ä»¶  ã€ä¼˜åŒ–方案一】拆分HAR导出文件  ã€ä¼˜åŒ–方案二】导入冷å¯åŠ¨æ–‡ä»¶æ—¶å…¨è·¯å¾„å±•å¼€  优化å‰åŽçš„对比数æ®å¦‚下: | 方案 | 阶段时长(毫秒) | |-----------|:----------:| | ä¼˜åŒ–å‰ | 140.1 | | 优化方案一(拆分HAR导出文件) | 62.9 | | 优化方案二(导入冷å¯åŠ¨æ–‡ä»¶æ—¶å…¨è·¯å¾„å±•å¼€ï¼‰ | 61.3 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œå› æ¤å¯ä»¥é€šè¿‡æ‹†åˆ†HAR包导出的Index.ets文件或导入冷å¯åŠ¨æ–‡ä»¶æ—¶è·¯å¾„å…¨å±•å¼€çš„æ–¹æ¡ˆï¼Œå‡å°‘应用冷å¯åЍä¸.ets文件执行耗时,从而æå‡åº”用冷å¯åŠ¨é€Ÿåº¦ã€‚ ### ä½¿ç”¨å»¶è¿ŸåŠ è½½Lazy-Importå‡å°‘冷å¯åŠ¨å†—ä½™æ–‡ä»¶æ‰§è¡Œ å¯ä»¥é€šè¿‡å»¶è¿ŸåŠ è½½ [lazy-import](../arkts-utils/arkts-lazy-import.md) 延缓对冷å¯åŠ¨æ—¶æš‚ä¸æ‰§è¡Œçš„å†—ä½™æ–‡ä»¶çš„åŠ è½½ï¼Œè€Œåœ¨åŽç»å¯¼å‡ºå˜é‡è¢«çœŸæ£ä½¿ç”¨æ—¶å†åŒæ¥åŠ è½½æ‰§è¡Œæ–‡ä»¶ï¼ŒèŠ‚çœèµ„æºä»¥æé«˜åº”用冷å¯åŠ¨æ€§èƒ½ã€‚ 详细使用指导请å‚考[å»¶è¿ŸåŠ è½½lazy-import使用指导](Lazy-Import-Instructions.md)。 ### å‡å°‘多个HSP/HAP对于相åŒHAR的引用 在应用开å‘的过程ä¸ï¼Œå¯ä»¥ä½¿ç”¨[HSP](../quick-start/in-app-hsp.md)或[HAR](../quick-start/har-package.md)的共享包方å¼å°†åŒç±»çš„æ¨¡å—进行整åˆï¼Œç”¨äºŽå®žçŽ°å¤šä¸ªæ¨¡å—æˆ–多个工程间共享ArkUI组件ã€èµ„æºç‰ç›¸å…³ä»£ç 。 由于共享包的动æ€å’Œé™æ€å·®å¼‚,在多HAP/HSP引用相åŒHAR包的情况下,会å˜åœ¨HAR包ä¸çš„å•例失效,从而影å“到应用冷å¯åŠ¨çš„æ€§èƒ½ã€‚ ã€ä¼˜åŒ–å‰ã€‘HAP包和HSP包分别引用相åŒHAR包  如上图所示,工程内å˜åœ¨ä¸‰ä¸ªæ¨¡å—,HAPåŒ…ä¸ºåº”ç”¨ä¸»å…¥å£æ¨¡å—,HSPä¸ºåº”ç”¨ä¸»ç•Œé¢æ˜¾ç¤ºæ¨¡å—,HAR_COMMON集æˆäº†æ‰€æœ‰é€šç”¨å·¥å…·ç±»ï¼Œå…¶ä¸funcResult为func方法的执行结果。 由于HAPå’ŒHSP模å—åŒæ—¶å¼•用HAR_COMMONæ¨¡å—æ—¶ä¼šç ´åHARçš„å•例模å¼ï¼Œæ‰€ä»¥HAPå’ŒHSP模å—使用**HAR_COMMON**ä¸çš„**funcResult**时,会导致func方法在两个模å—åŠ è½½æ—¶å„æ‰§è¡Œä¸€æ¬¡ï¼Œä½¿å¾—文件执行时间耗时增长。 如果仅从性能的角度考虑,å¯ä»¥ä½¿ç”¨ä»¥ä¸‹æ–¹å¼è¿›è¡Œä¿®æ”¹ï¼Œä»Žè€Œè¾¾åˆ°ç¼©çŸå†·å¯åŠ¨é˜¶æ®µè€—æ—¶çš„ç›®çš„ã€‚ ã€ä¼˜åŒ–åŽã€‘切æ¢ä¸ºHAP包和HAR包分别引用相åŒHAR包  >**说明:** > > 1. 在多HAP/HSP引用相åŒHAR包的情况下,若HSP包和HAR包å‡èƒ½æ»¡è¶³ä¸šåŠ¡éœ€æ±‚ï¼Œå»ºè®®å°†HSP包改æˆHAR包。 > 2. 若使用的HSPä¸ºé›†æˆæ€HSP,å¯è·³è¿‡è¯¥ä¼˜åŒ–方案。 以下为示例代ç : 1. 在被引用HAR_COMMON包ä¸å†™å…¥åŠŸèƒ½ç¤ºä¾‹ã€‚ ```ts // har_common/src/main/ets/utils/Utils.ets const LARGE_NUMBER = 100000000; function func(): number { let count = 0; while (count < LARGE_NUMBER) { count++; } return count; } export let funcResult = func(); ``` 2. 分别通过使用HSP包和HAR包æ¥å¼•用该HAR_COMMON包ä¸çš„功能进行性能对比实验。 - 使用HAP包和HSP包引用该HAR_COMMON包ä¸çš„功能。 HAP包引用HAR_COMMON包ä¸çš„功能。 ```ts // entry/src/main/ets/pages/Index.ets import { MainPage } from 'hsp_library'; import { funcResult } from 'har_common'; ``` HSP包引用HAR_COMMON包ä¸çš„功能。 ```ts // hsp_library/src/main/ets/pages/MainPage.ets import { funcResult } from 'har_common'; ``` - 使用HAP包和HAR包引用该HAR_COMMON包ä¸çš„功能。 HAP包引用HAR_COMMON包ä¸çš„功能。 ```ts // entry/src/main/ets/pages/Index.ets import { MainPage } from 'har_library'; import { funcResult } from 'har_common'; ``` HAR包引用HAR_COMMON包ä¸çš„功能。 ```ts // har_library/src/main/ets/pages/MainPage.ets import { funcResult } from 'har_common'; ``` 下é¢å¯¹ä¼˜åŒ–å‰åŽå¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžã€‚分æžé˜¶æ®µçš„起点为å¯åЍAbility(å³`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用第一次接到vsync(å³`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。 ã€ä¼˜åŒ–å‰ã€‘使用HSP包  ã€ä¼˜åŒ–åŽã€‘使用HAR代替HSP  优化å‰åŽçš„对比数æ®å¦‚下: | 方案 | 阶段时长(毫秒) | |------------------|:----------:| | (优化å‰ï¼‰ä½¿ç”¨HSP包 | 3125 | | (优化åŽï¼‰ä½¿ç”¨HAR代替HSP | 853.9 | 从测试数æ®å¯ä»¥çœ‹å‡ºï¼Œå°†HSP替æ¢ä¸ºHAR包åŽï¼Œåº”用å¯åŠ¨çš„é˜¶æ®µè€—æ—¶æ˜Žæ˜¾ç¼©çŸã€‚ >**说明:** > > 上述示例为凸显出差异,func执行函数循环次数为100000000,开å‘è€…å®žé™…ä¿®æ”¹åŽæ”¶ç›Šéœ€æ ¹æ®å®žé™…情况测试。 ## 3ã€ç¼©çŸAbilityStage生命周期阶段耗时 è¯¥é˜¶æ®µä¸»è¦æ˜¯AbilityStageçš„å¯åŠ¨ç”Ÿå‘½å‘¨æœŸï¼Œæ‰§è¡Œç›¸åº”çš„ç”Ÿå‘½å‘¨æœŸå›žè°ƒã€‚ ### é¿å…在AbilityStage生命周期回调接å£è¿›è¡Œè€—æ—¶æ“作 在应用å¯åЍæµç¨‹ä¸ï¼Œç³»ç»Ÿä¼šæ‰§è¡ŒAbilityStageçš„ç”Ÿå‘½å‘¨æœŸå›žè°ƒå‡½æ•°ã€‚å› æ¤ï¼Œä¸å»ºè®®åœ¨è¿™äº›å›žè°ƒå‡½æ•°ä¸æ‰§è¡Œè€—时过长的æ“作,耗时æ“作建议通过异æ¥ä»»åŠ¡å»¶è¿Ÿå¤„ç†æˆ–者放到其他线程执行。 在这些生命周期回调里,推èå¼€å‘者åªåšå¿…è¦çš„æ“ä½œï¼Œè¯¦æƒ…å¯ä»¥å‚考:[AbilityStage组件容器](../application-models/abilitystage.md)。 以下为示例代ç : ```ts const LARGE_NUMBER = 10000000; const DELAYED_TIME = 1000; export default class MyAbilityStage extends AbilityStage { onCreate(): void { // 耗时æ“作 // this.computeTask(); this.computeTaskAsync(); // 异æ¥ä»»åŠ¡ } onAcceptWant(want: Want): string { // ä»…specified模å¼ä¸‹è§¦å‘ return 'MyAbilityStage'; } computeTask(): void { let count = 0; while (count < LARGE_NUMBER) { count++; } } private computeTaskAsync(): void { setTimeout(() => { // 这里使用setTimeoutæ¥å®žçް异æ¥å»¶è¿Ÿè¿è¡Œ this.computeTask(); }, DELAYED_TIME); } } ``` 下é¢ä½¿ç”¨[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`的开始点)。 对比数æ®å¦‚下: | | 阶段开始(ç§’) | 阶段结æŸ(ç§’) | 阶段时长(ç§’) | | ---------------------- | -------------- | -------------- | ------------ | | 优化å‰åŒæ¥æ‰§è¡Œè€—æ—¶æ“作 | 2124.915558194 | 2127.041354575 | 2.125796381 | | 优化åŽå¼‚æ¥æ‰§è¡Œè€—æ—¶æ“作 | 4186.436835246 | 4186.908777335 | 0.471942089 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œæ•…é¿å…在AbilityStage生命周期回调接å£è¿›è¡Œè€—æ—¶æ“作对缩çŸAbilityStage生命周期阶段耗时是有效的。 ## 4ã€ç¼©çŸAbility生命周期阶段耗时 è¯¥é˜¶æ®µä¸»è¦æ˜¯Abilityçš„å¯åŠ¨ç”Ÿå‘½å‘¨æœŸï¼Œæ‰§è¡Œç›¸åº”çš„ç”Ÿå‘½å‘¨æœŸå›žè°ƒã€‚ ### éžUI耗时æ“作并行化 在应用å¯åЍæµç¨‹ä¸ï¼Œä¸»è¦èšç„¦åœ¨æ‰§è¡ŒUI相关æ“作ä¸ï¼Œä¸ºäº†æ›´å¿«çš„能显示首页内容,ä¸å»ºè®®åœ¨ä¸»çº¿ç¨‹ä¸æ‰§è¡ŒéžUI相关的耗时æ“作,耗时æ“作建议通过异æ¥ä»»åŠ¡è¿›è¡Œå»¶è¿Ÿå¤„ç†æˆ–放到其他åçº¿ç¨‹ä¸æ‰§è¡Œï¼Œçº¿ç¨‹å¹¶å‘方案å¯ä»¥å‚考:[TaskPoolå’ŒWorker的对比实践](../arkts-utils/multi-thread-concurrency-overview.md)。 在冷å¯åŠ¨è¿‡ç¨‹ä¸å¦‚æžœå˜åœ¨å›¾ç‰‡ä¸‹è½½ã€ç½‘络请求å‰ç½®æ•°æ®ã€æ•°æ®ååºåˆ—化ç‰éžUIæ“作å¯ä»¥æ ¹æ®å¼€å‘者实际情况移至å线程ä¸è¿›è¡Œï¼Œå‚è€ƒä¸‹é¢æ–‡ç« :[é¿å…åœ¨ä¸»çº¿ç¨‹ä¸æ‰§è¡Œè€—æ—¶æ“作](avoid_time_consuming_operations_in_mainthread.md)。 ### é¿å…在Ability生命周期回调接å£è¿›è¡Œè€—æ—¶æ“作 在应用å¯åЍæµç¨‹ä¸ï¼Œç³»ç»Ÿä¼šæ‰§è¡ŒAbilityçš„ç”Ÿå‘½å‘¨æœŸå›žè°ƒå‡½æ•°ã€‚å› æ¤ï¼Œä¸å»ºè®®åœ¨è¿™äº›å›žè°ƒå‡½æ•°ä¸æ‰§è¡Œè€—时过长的æ“作,耗时æ“作建议通过异æ¥ä»»åŠ¡å»¶è¿Ÿå¤„ç†æˆ–者放到其他线程执行。 在这些生命周期回调里,推èå¼€å‘者åªåšå¿…è¦çš„æ“ä½œï¼Œä¸‹é¢ä»¥UIAbility为例进行说明。关于UIAbility组件生命周期的详细说明,å‚è§[UIAbility组件生命周期](../application-models/uiability-lifecycle.md)。 ```ts const LARGE_NUMBER = 10000000; const DELAYED_TIME = 1000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', 'Ability onCreate'); // 耗时æ“作 // this.computeTask(); this.computeTaskAsync(); // 异æ¥ä»»åŠ¡ } onDestroy(): void { hilog.info(0x0000, 'testTag', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { hilog.info(0x0000, 'testTag', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: ' + JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: ' + JSON.stringify(data) ?? ''); }); // 耗时æ“作 // this.computeTask(); this.computeTaskAsync(); // 异æ¥ä»»åŠ¡ } onWindowStageDestroy(): void { hilog.info(0x0000, 'testTag', 'Ability onWindowStageDestroy'); } onForeground(): void { hilog.info(0x0000, 'testTag', 'Ability onForeground'); // 耗时æ“作 // this.computeTask(); this.computeTaskAsync(); // 异æ¥ä»»åŠ¡ } onBackground(): void { hilog.info(0x0000, 'testTag', 'Ability onBackground'); } computeTask(): void { let count = 0; while (count < LARGE_NUMBER) { count++; } } private computeTaskAsync(): void { setTimeout(() => { // 这里使用setTimeoutæ¥å®žçް异æ¥å»¶è¿Ÿè¿è¡Œ this.computeTask(); }, DELAYED_TIME); } } ``` 下é¢ä½¿ç”¨[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`的开始点)。 对比数æ®å¦‚下: | 方案 | 阶段开始(ç§’) | 阶段结æŸ(ç§’) | 阶段时长(ç§’) | |-------------| -------------- | -------------- | ------------ | | 优化å‰åŒæ¥æ‰§è¡Œè€—æ—¶æ“作 | 1954.987630036 | 1957.565964504 | 2.578334468 | | 优化åŽå¼‚æ¥æ‰§è¡Œè€—æ—¶æ“作 | 4186.436835246 | 4186.908777335 | 0.471942089 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œæ•…é¿å…在Ability生命周期回调接å£è¿›è¡Œè€—æ—¶æ“作对缩çŸAbility生命周期阶段耗时是有效的。 ## 5ã€ç¼©çŸåŠ è½½ç»˜åˆ¶é¦–é¡µé˜¶æ®µè€—æ—¶ è¯¥é˜¶æ®µä¸»è¦æ˜¯åŠ è½½é¦–é¡µå†…å®¹ã€æµ‹é‡å¸ƒå±€ã€åˆ·æ–°ç»„件并绘制。 ### 自定义组件生命周期回调接å£é‡Œé¿å…耗时æ“作 è‡ªå®šä¹‰ç»„ä»¶çš„ç”Ÿå‘½å‘¨æœŸå˜æ›´ä¼šè°ƒç”¨ç›¸åº”的回调函数。 aboutToAppear函数会在创建自定义组件实例åŽï¼Œé¡µé¢ç»˜åˆ¶ä¹‹å‰æ‰§è¡Œï¼Œä»¥ä¸‹ä»£ç 在aboutToAppearä¸å¯¹è€—时间的计算任务进行了异æ¥å¤„ç†ï¼Œé¿å…åœ¨è¯¥æŽ¥å£æ‰§è¡Œè¯¥è€—æ—¶æ“作,ä¸é˜»å¡žé¡µé¢ç»˜åˆ¶ã€‚ 以下为示例代ç : ```ts const LARGE_NUMBER = 10000000; const DELAYED_TIME = 1000; @Entry @Component struct Index { @State private text: string = ""; private count: number = 0; aboutToAppear() { // 耗时æ“作 // this.computeTask(); this.computeTaskAsync(); // 异æ¥ä»»åŠ¡ let context = getContext(this) as Context; this.text = context.resourceManager.getStringSync($r('app.string.startup_text')); } build() { Column({ space: 10 }) { Text(this.text).fontSize(50) } .width('100%') .height('100%') .padding(10) } computeTask(): void { this.count = 0; while (this.count < LARGE_NUMBER) { this.count++; } let context = getContext(this) as Context; this.text = context.resourceManager.getStringSync($r('app.string.task_text')); } // è¿ç®—任务异æ¥å¤„ç† private computeTaskAsync(): void { setTimeout(() => { // 这里使用setTimeoutæ¥å®žçް异æ¥å»¶è¿Ÿè¿è¡Œ this.computeTask(); }, DELAYED_TIME); } } ``` 下é¢ä½¿ç”¨[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`的开始点)。 对比数æ®å¦‚下: | 方案 | 阶段开始(ç§’) | 阶段结æŸ(ç§’) | 阶段时长(ç§’) | |-------------| -------------- | -------------- | ------------ | | 优化å‰åŒæ¥æ‰§è¡Œè€—æ—¶æ“作 | 3426.272974492 | 3431.785898837 | 5.512924345 | | 优化åŽå¼‚æ¥æ‰§è¡Œè€—æ—¶æ“作 | 4186.436835246 | 4186.908777335 | 0.471942089 | å¯è§é˜¶æ®µæ—¶é•¿å·²ç¼©çŸï¼Œå› æ¤åœ¨è‡ªå®šä¹‰ç»„件生命周期回调接å£ä¸é¿å…耗时æ“作å¯ä»¥ç¼©çŸåŠ è½½ç»˜åˆ¶é¦–é¡µé˜¶æ®µè€—æ—¶ã€‚ ## 6ã€ç¼©çŸç½‘络数æ®äºŒæ¬¡åˆ·æ–°é˜¶æ®µè€—æ—¶ è¯¥é˜¶æ®µä¸»è¦æ˜¯åº”ç”¨æ ¹æ®ä¸šåŠ¡éœ€è¦å¯¹ç½‘络数æ®è¿›è¡Œè¯·æ±‚ã€å¤„ç†ã€äºŒæ¬¡åˆ·æ–°ã€‚ ### 网络请求æå‰å‘é€ å½“å‰å¤§å¤šæ•°åº”用的首页内容需从网络获å–,å‘é€ç½‘络请求的时机显得尤为é‡è¦ã€‚应用å‘é€ç½‘络请求åŽç‰å¾…网络数æ®çš„返回,网络请求的这段时间应用å¯ä»¥ç»§ç»æ‰§è¡Œå¯åЍæµç¨‹ï¼Œç›´åˆ°ç½‘络数æ®è¿”回åŽè¿›è¡Œè§£æžï¼Œååºåˆ—化之åŽå°±å¯ä»¥åŠ è½½é¦–é¡µæ•°æ®ï¼Œå› æ¤ç½‘络请求的å‘起时机越早,整个冷å¯åŠ¨çš„å®Œæˆæ—¶å»¶é˜¶æ®µè¶ŠçŸã€‚ å¯å°†ç½‘络请求åŠç½‘络请求å‰çš„åˆå§‹åŒ–æµç¨‹æ”¾ç½®åœ¨AbilityStage/UIAbilityçš„onCreate()生命周期ä¸ï¼Œåœ¨AbilityStage/UIAbilityä¸ä»…执行网络相关预处ç†ï¼Œç‰å¾…网络请求å‘é€åŽå¯ç»§ç»æ‰§è¡Œé¦–页数æ®å‡†å¤‡ã€UI相关æ“作。在æœåŠ¡ç«¯å¤„ç†æµç¨‹ç›¸åŒçš„æƒ…况下,应用å¯ä»¥æ›´æ—©çš„æ‹¿åˆ°ç½‘络数æ®å¹¶è¡Œå±•示。 ã€ä¼˜åŒ–å‰ã€‘åº”ç”¨é¦–é¡µæ¡†æž¶åŠ è½½æ—¶è¿›è¡Œç½‘ç»œæ•°æ®è¯·æ±‚  将网络请求æå‰è‡³AbilityStage/UIAbility生命的onCreate()生命周期回调函数ä¸ï¼Œå¯ä»¥å°†é¦–刷或二刷的时间æå‰ï¼Œå‡å°‘用户ç‰å¾…时间。æ¤å¤„为了体现性能收益,将网络请求放到了更早的AbilityStageçš„onCreate()生命周期回调ä¸ã€‚ ã€ä¼˜åŒ–åŽã€‘网络请求æå‰è‡³AbilityStageçš„onCreate()å‘¨æœŸå›žè°ƒä¸  以下为示例代ç : ã€ä¼˜åŒ–å‰ã€‘ï¼šåœ¨é¦–é¡µæ ¹ç»„ä»¶çš„onAppear()生命周期回调ä¸å‘起网络请求。 ```ts // entry/src/main/ets/pages/Index.ets import { httpRequest } from '../utils/NetRequest'; import { number } from '../utils/Calculator'; AppStorage.link('netData'); PersistentStorage.persistProp('netData', undefined); @Entry @Component struct Index { @State message: string = 'Hello World' + number; // 为了体现性能收益,引用耗时函数的执行结果number @StorageLink('netData') netData: PixelMap | undefined = undefined; build(){ Row(){ Image(this.netData) .objectFit(ImageFit.Contain) .width('50%') .height('50%') } .onAppear(() => { // å‘é€ç½‘络请求 httpRequest(); }) } } // entry/src/main/ets/utils/NetRequest.ets import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; import { http } from '@kit.NetworkKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { image } from '@kit.ImageKit'; // 通过httpçš„requestæ–¹æ³•ä»Žç½‘ç»œä¸‹è½½å›¾ç‰‡èµ„æº export function httpRequest() { hiTraceMeter.startTrace('Http Request', 1); http.createHttp() // 实际开å‘需è¦å°†"https://www.example1.com/POST?e=f&g=h"æ›¿æ¢æˆä¸ºçœŸå®žè¦è®¿é—®çš„ç½‘ç«™åœ°å€ .request('https://www.example1.com/POST?e=f&g=h', (error: BusinessError, data: http.HttpResponse) => { if (error) { // ä¸‹è½½å¤±è´¥æ—¶ä¸æ‰§è¡ŒåŽç»é€»è¾‘ return; } // 处ç†ç½‘ç»œè¯·æ±‚è¿”å›žçš„æ•°æ® transcodePixelMap(data); } ) } // 使用createPixelMapå°†ArrayBuffer类型的图片装æ¢ä¸ºPixelMap类型 function transcodePixelMap(data: http.HttpResponse) { if (http.ResponseCode.OK === data.responseCode) { const imageData: ArrayBuffer = data.result as ArrayBuffer; // 通过ArrayBuffer创建图片æºå®žä¾‹ const imageSource: image.ImageSource = image.createImageSource(imageData); const options: image.InitializationOptions = { 'alphaType': 0, // 逿˜Žåº¦ 'editable': false, // 是å¦å¯ç¼–辑 'pixelFormat': 3, // åƒç´ æ ¼å¼ 'scaleMode': 1, // 缩略值 'size': { height: 100, width: 100 } }; // åˆ›å»ºå›¾ç‰‡å¤§å° // 通过属性创建PixelMap imageSource.createPixelMap(options).then((pixelMap: PixelMap) => { AppStorage.set('netData', pixelMap); hiTraceMeter.finishTrace('Http Request', 1); }); } } // entry/src/main/ets/utils/Calculator.ets const LARGE_NUMBER = 100000000; function computeTask(): number { let count = 0; while (count < LARGE_NUMBER) { count++; } return count; } export let number = computeTask(); ``` ã€ä¼˜åŒ–åŽã€‘ 1. 在NetRequest.etsä¸è¿›è¡ŒHttpè¯·æ±‚ä»¥åŠæ•°æ®å¤„ç†ã€‚ ```ts // NetRequest.ets import { hiTraceMeter } from '@kit.PerformanceAnalysisKit'; import { http } from '@kit.NetworkKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { image } from '@kit.ImageKit'; // 通过httpçš„requestæ–¹æ³•ä»Žç½‘ç»œä¸‹è½½å›¾ç‰‡èµ„æº export function httpRequest() { hiTraceMeter.startTrace('Http Request', 1); http.createHttp() // 实际开å‘需è¦å°†"https://www.example1.com/POST?e=f&g=h"æ›¿æ¢æˆä¸ºçœŸå®žè¦è®¿é—®çš„ç½‘ç«™åœ°å€ .request('https://www.example1.com/POST?e=f&g=h', (error: BusinessError, data: http.HttpResponse) => { if (error) { // ä¸‹è½½å¤±è´¥æ—¶ä¸æ‰§è¡ŒåŽç»é€»è¾‘ return; } // 处ç†ç½‘ç»œè¯·æ±‚è¿”å›žçš„æ•°æ® transcodePixelMap(data); } ) } // 使用createPixelMapå°†ArrayBuffer类型的图片装æ¢ä¸ºPixelMap类型 function transcodePixelMap(data: http.HttpResponse) { if (http.ResponseCode.OK === data.responseCode) { const imageData: ArrayBuffer = data.result as ArrayBuffer; // 通过ArrayBuffer创建图片æºå®žä¾‹ const imageSource: image.ImageSource = image.createImageSource(imageData); const options: image.InitializationOptions = { 'alphaType': 0, // 逿˜Žåº¦ 'editable': false, // 是å¦å¯ç¼–辑 'pixelFormat': 3, // åƒç´ æ ¼å¼ 'scaleMode': 1, // 缩略值 'size': { height: 100, width: 100 } }; // åˆ›å»ºå›¾ç‰‡å¤§å° // 通过属性创建PixelMap imageSource.createPixelMap(options).then((pixelMap: PixelMap) => { AppStorage.set('netData', pixelMap); hiTraceMeter.finishTrace('Http Request', 1); }); } } ``` 2. 在AbilityStageçš„onCreate()生命周期回调ä¸å‘起网络请求。 ```ts // MyAbilityStage.ets import { AbilityStage, Want } from '@kit.AbilityKit'; import { httpRequest } from '../utils/NetRequest'; export default class MyAbilityStage extends AbilityStage { onCreate(): void { // å‘é€ç½‘络请求 httpRequest(); } onAcceptWant(want: Want): string { // ä»…specified模å¼ä¸‹è§¦å‘ return 'MyAbilityStage'; } } ``` 3. 在首页Index.etsä¸å±•示请求获å–的图片。 ```ts // Index.ets import { number } from '../utils/Calculator'; AppStorage.link('netData'); PersistentStorage.persistProp('netData', undefined); @Entry @Component struct Index { @State message: string = 'Hello World' + number; // 为了体现性能收益,引用耗时函数的执行结果number @StorageLink('netData') netData: PixelMap | undefined = undefined; build() { Row() { Image(this.netData) .objectFit(ImageFit.Contain) .width('50%') .height('50%') } .onDisAppear(() => { AppStorage.set('netData', undefined); }) .height('100%') .width('100%') } } ``` 下é¢å¯¹ä¼˜åŒ–å‰åŽå¯åŠ¨æ€§èƒ½è¿›è¡Œå¯¹æ¯”åˆ†æžï¼Œåˆ†æžé˜¶æ®µçš„起点为å¯åЍAbility(å³`H:void OHOS::AppExecFwk::MainThread::HandleLaunchAbility`的开始点),阶段终点为应用接收到网络数æ®è¿”回åŽçš„首帧刷新(å³`H:ReceiveVsync dataCount:24Bytes now:timestamp expectedEnd:timestamp vsyncId:int`的开始点)。 ã€ä¼˜åŒ–å‰ã€‘ä¼˜åŒ–ç½‘ç»œè¯·æ±‚æ—¶æœºå‰  ã€ä¼˜åŒ–åŽã€‘ä¼˜åŒ–ç½‘ç»œè¯·æ±‚æ—¶æœºåŽ  对比数æ®å¦‚下: | 方案 | 阶段时长(毫秒) | |-----------|:----------:| | ä¼˜åŒ–ç½‘ç»œè¯·æ±‚æ—¶æœºå‰ | 1700 | | ä¼˜åŒ–ç½‘ç»œè¯·æ±‚æ—¶æœºåŽ | 885.3 | å› æ¤ï¼Œå¯ä»¥é€šè¿‡æå‰ç½‘络请求的方å¼å‡å°‘应用冷å¯åŠ¨è€—æ—¶ã€‚ ### 使用本地缓å˜é¦–é¡µæ•°æ® ä½¿ç”¨æœ¬åœ°ç¼“å˜é¦–é¡µæ•°æ®æ˜¯ä¼˜åŒ–应用性能的关键一环。它能有效缩çŸå†·å¯åŠ¨æ—¶çš„ç™½å±æˆ–ç™½å—æ—¶é—´ï¼Œæ˜¾è‘—æå‡ç”¨æˆ·ä½“验。该ç–略通过预先å˜å‚¨å¹¶ä¼˜å…ˆå±•示缓å˜ä¸çš„首页数æ®ï¼Œå‡å°‘了对外部资æºï¼ˆå¦‚网络)的ä¾èµ–ï¼Œä»Žè€ŒåŠ å¿«æ•°æ®åŠ è½½é€Ÿåº¦ã€‚å½“æ•°æ®æ›´æ–°æ—¶ï¼Œåº”ç”¨åˆ™æ™ºèƒ½åœ°ä»Žç½‘ç»œç‰æ¸ é“èŽ·å–æœ€æ–°å†…容,确ä¿ä¿¡æ¯çš„æ—¶æ•ˆæ€§ä¸Žå‡†ç¡®æ€§ã€‚使用本地缓å˜é¦–页数æ®ï¼Œä¸ä»…让应用å“应更迅速,还显著优化了整体è¿è¡Œæµç•…åº¦ï¼Œä¸ºç”¨æˆ·å¸¦æ¥æ›´åŠ é¡ºç•…çš„ä½“éªŒã€‚æ›´å¤šå®žçŽ°ç»†èŠ‚ä¸Žæ€§èƒ½æå‡åˆ†æžï¼Œè¯·å‚è§[åˆç†ä½¿ç”¨ç¼“å˜æå‡æ€§èƒ½](./reasonable_using_cache_improve_performance.md)。