1# Dynamic Import 2 3## Overview 4 5When an application loads a page, importing statically all modules significantly slows the loading, and it is often the case that these modules are not all needed. For example, when the home page uses the **Navigation** component, loading the home page loads all subpages by default. As a result, the loading takes a long time, especially when there are a large number of subpages. In effect, the subpages are irrelevant to home page rendering. If they are loaded at a later time, the home page load time can be greatly reduced. 6This is where dynamic import comes into play. In this document, we will improve the performance of an application by dynamically importing modules. 7 8## Example 9 10| Home page | Subpage | 11|------------------------------------------|--------------------------------------------| 12|  |  | 13 14The following example compares static import and dynamic import of the **Navigation** component to describe how to trigger on-demand loading during redirection. 15 16### Static Import 17 18When using the **Navigation** component, you may import subpage components to the home page and add methods to buttons to implement redirection. The following code shows a static import example. 19 201. Subpage modules are imported. The **Navigation** component uses these modules to redirect the user to subpages. As the subpages are not immediately needed when the user accesses the home page, loading these subpages is redundant and slows down home page loading. 21 ```ts 22 import { pageOne, pageOneData } from './pageOne'; 23 import { pageTwo, pagesTwoData } from './pageTwo'; 24 ... 25 import router from '@ohos.router'; 26 ``` 272. The home page uses the **Navigation** component to redirect the user to different subpages when they click a specific button. 28 ```ts 29 @Provide('pathInfos') pageInfos: NavPathStack = new NavPathStack(); 30 31 @Builder 32 PageMap(name: string) { 33 if (name === 'pageOne') { 34 pageOne(new pagesOneData(name, this.pageInfos)); 35 } else if (name === 'pageTwo') { 36 pageTwo(new pagesTwoData(name, this.pageInfos)); 37 } 38 ... 39 } 40 41 build() { 42 Navigation(this.pageInfos) { 43 Button('Back', { stateEffect: true, type: ButtonType.Capsule }) 44 .onClick(() => { 45 router.back(); 46 }) 47 Column() { 48 Button('pageOne', { stateEffect: true, type: ButtonType.Capsule }) 49 .onClick(() => { 50 this.pageInfos.pushPath({ name: 'pageOne' }); // Push the navigation destination page specified by name to the navigation stack. 51 }) 52 Button('pageTwo', { stateEffect: true, type: ButtonType.Capsule }) 53 .onClick(() => { 54 this.pageInfos.pushPath({ name: 'pageTwo' }); 55 }) 56 ... 57 } 58 }.title('Home').navDestination(this.PageMap) 59 } 60 ``` 61 62### Dynamic Import 63 64If the **Navigation** component loads all modules statically at a time, the loading of the home page can be slow, especially when there are a large number of complex child components. To reduce page load time, you can use dynamic import, so that child components are dynamically imported as needed during page redirection. To implement dynamic import, perform the following steps: 65 661. Encapsulate the **pageOne** component to be dynamically imported through the **PageOneLoader** function. This way, when the **PageOneLoader** function is called, the **pageOne** page is rendered. 67 ```ts 68 import { pageOne } from './pageOne'; 69 70 @Builder 71 export function PageOneLoader() { 72 pageOne(); 73 } 74 ``` 752. Because the **navDestination** component in **PageMap** of the **Navigation** component cannot directly load components (**import** is a function and cannot be referenced in components), you need to declare the **@BuilderParam PageOneLoader** function and initialize it when the corresponding button is clicked. This way, **this.PageOneLoader()** can be called in the **navDestination** component to load the **pageOne** component. 76To dynamically load **pageOne** on the home page **DynamicHome**, perform the following steps: 77 a. Define the **@BuilderParam PageOneLoader: () => void** function in the home page **DynamicHome** to receive the result of asynchronously importing **pageOneLoader** by **await import**. 78 ```ts 79 @BuilderParam PageOneLoader: () => void; 80 ``` 81 b. Defines an asynchronous function so that when the button is clicked, **PageOneLoader** is initialized. 82 ```ts 83 async loadPageOne(key: string){ 84 if (key === "pageOne") { 85 let PageObj: ESObject = await import("../pages/PageOneLoader"); 86 this.PageOneLoader = PageObj.PageOneLoader; 87 } 88 } 89 ``` 90 c. Click the button to trigger the click function and call **loadPageOne**. In this case, **@BuilderParam PageOneLoader** is initialized and **Navigation** is used to load the component. 91 ```ts 92 private onEntryClick(): void { 93 try { 94 this.loadPageOne('pageOne'); 95 this.pageInfos.clear(); 96 this.pageInfos.pushPathByName('pageOne', ''); 97 logger.info('DynamicImport Success'); 98 } catch (error) { 99 logger.info('DynamicImport Fail'); 100 } 101 } 102 ``` 103 d. Trigger the initialized **PageOneLoader** function in **PageMap** to dynamically load the **PageOne** component. 104 ```ts 105 @Builder 106 PageMap(name: string) { 107 if (name === 'pageOne') { 108 this.PageOneLoader(); 109 } 110 } 111 ``` 112The complete code of the **DynamicHome** home page is as follows: 113```ts 114import router from '@ohos.router'; 115import { logger } from '../../ets/utils/Logger'; 116 117@Entry 118@Component 119struct DynamicHome { 120 @Provide('pathInfos') pageInfos: NavPathStack = new NavPathStack(); 121 @State active: boolean = false; 122 @BuilderParam PageOneLoader: () => void; 123 124 @Builder 125 PageMap(name: string) { 126 if (name === 'pageOne') { 127 this.PageOneLoader(); 128 } 129 } 130 131 build() { 132 Navigation(this.pageInfos) { 133 Column() { 134 Button('Back', { stateEffect: true, type: ButtonType.Capsule }) 135 .width('80%') 136 .height(40) 137 .margin(20) 138 .onClick(() => { 139 router.back(); 140 }) 141 Button('PageOne-Dynamic', { stateEffect: true, type: ButtonType.Capsule }) 142 .width('80%') 143 .height(40) 144 .margin(20) 145 .onClick(() => { 146 this.onEntryClick(); 147 }) 148 } 149 }.title('HOME').navDestination(this.PageMap) 150 } 151 152 async loadPageOne(key: String) { 153 if (key === "pageOne") { 154 let PageObj: ESObject = await import("../pages/PageOneLoader"); 155 this.PageOneLoader = PageObj.PageOneLoader; 156 } 157 } 158 159 // Trigger dynamic loading. 160 private onEntryClick(): void { 161 try { 162 this.loadPageOne('pageOne'); 163 this.pageInfos.clear(); 164 this.pageInfos.pushPathByName('pageOne', ''); 165 logger.info('DynamicImport Success'); 166 } catch (error) { 167 logger.info('DynamicImport Fail'); 168 } 169 } 170} 171``` 172In sum, when there are a large number of subpages in the **Navigation** component, using static import to load all subpages at once can significantly slow the loading of the home page. To reduce the page load time and overall resource consumption and prevent the main thread from being blocked, use dynamic import so subpages are loaded on demand. 173