1e41f4b71Sopenharmony_ci# Dynamic Import
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Overview
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciWhen 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.
6e41f4b71Sopenharmony_ciThis is where dynamic import comes into play. In this document, we will improve the performance of an application by dynamically importing modules.
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci## Example
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci| Home page                                      | Subpage                                       |
11e41f4b71Sopenharmony_ci|------------------------------------------|--------------------------------------------|
12e41f4b71Sopenharmony_ci| ![Home](./figures/dynamic-import-home.png) | ![Subpage](./figures/dynamic-import-pages.png) |
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciThe following example compares static import and dynamic import of the **\<Navigation>** component to describe how to trigger on-demand loading during redirection.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci### Static Import
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ciWhen 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.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci1. 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.
21e41f4b71Sopenharmony_ci    ```ts
22e41f4b71Sopenharmony_ci    import { pageOne, pageOneData } from './pageOne';
23e41f4b71Sopenharmony_ci    import { pageTwo, pagesTwoData } from './pageTwo';
24e41f4b71Sopenharmony_ci    ...
25e41f4b71Sopenharmony_ci    import router from '@ohos.router';
26e41f4b71Sopenharmony_ci    ```
27e41f4b71Sopenharmony_ci2. The home page uses the **\<Navigation>** component to redirect the user to different subpages when they click a specific button.
28e41f4b71Sopenharmony_ci    ```ts
29e41f4b71Sopenharmony_ci    @Provide('pathInfos') pageInfos: NavPathStack = new NavPathStack();
30e41f4b71Sopenharmony_ci    
31e41f4b71Sopenharmony_ci    @Builder
32e41f4b71Sopenharmony_ci    PageMap(name: string) {
33e41f4b71Sopenharmony_ci      if (name === 'pageOne') {
34e41f4b71Sopenharmony_ci        pageOne(new pagesOneData(name, this.pageInfos));
35e41f4b71Sopenharmony_ci      } else if (name === 'pageTwo') {
36e41f4b71Sopenharmony_ci        pageTwo(new pagesTwoData(name, this.pageInfos));
37e41f4b71Sopenharmony_ci      }
38e41f4b71Sopenharmony_ci      ...
39e41f4b71Sopenharmony_ci    }
40e41f4b71Sopenharmony_ci    
41e41f4b71Sopenharmony_ci    build() {
42e41f4b71Sopenharmony_ci      Navigation(this.pageInfos) {
43e41f4b71Sopenharmony_ci        Button('Back', { stateEffect: true, type: ButtonType.Capsule })
44e41f4b71Sopenharmony_ci          .onClick(() => {
45e41f4b71Sopenharmony_ci             router.back();
46e41f4b71Sopenharmony_ci          })
47e41f4b71Sopenharmony_ci        Column() {
48e41f4b71Sopenharmony_ci          Button('pageOne', { stateEffect: true, type: ButtonType.Capsule })
49e41f4b71Sopenharmony_ci            .onClick(() => {
50e41f4b71Sopenharmony_ci               this.pageInfos.pushPath({ name: 'pageOne' }); // Push the navigation destination page specified by name to the navigation stack.
51e41f4b71Sopenharmony_ci            })
52e41f4b71Sopenharmony_ci          Button('pageTwo', { stateEffect: true, type: ButtonType.Capsule })
53e41f4b71Sopenharmony_ci            .onClick(() => {
54e41f4b71Sopenharmony_ci               this.pageInfos.pushPath({ name: 'pageTwo' });
55e41f4b71Sopenharmony_ci            })
56e41f4b71Sopenharmony_ci          ...
57e41f4b71Sopenharmony_ci        }
58e41f4b71Sopenharmony_ci      }.title('Home').navDestination(this.PageMap)
59e41f4b71Sopenharmony_ci    }
60e41f4b71Sopenharmony_ci    ```
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ci### Dynamic Import
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ciIf 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:
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci1. 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.
67e41f4b71Sopenharmony_ci    ```ts
68e41f4b71Sopenharmony_ci    import { pageOne } from './pageOne';
69e41f4b71Sopenharmony_ci    
70e41f4b71Sopenharmony_ci    @Builder
71e41f4b71Sopenharmony_ci    export function PageOneLoader() {
72e41f4b71Sopenharmony_ci      pageOne();
73e41f4b71Sopenharmony_ci    }
74e41f4b71Sopenharmony_ci    ```
75e41f4b71Sopenharmony_ci2. 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.
76e41f4b71Sopenharmony_ciTo dynamically load **pageOne** on the home page **DynamicHome**, perform the following steps: 
77e41f4b71Sopenharmony_ci   a. Define the **@BuilderParam PageOneLoader: () => void** function in the home page **DynamicHome** to receive the result of asynchronously importing **pageOneLoader** by **await import**.
78e41f4b71Sopenharmony_ci    ```ts
79e41f4b71Sopenharmony_ci    @BuilderParam PageOneLoader: () => void;
80e41f4b71Sopenharmony_ci    ```
81e41f4b71Sopenharmony_ci   b. Defines an asynchronous function so that when the button is clicked, **PageOneLoader** is initialized.
82e41f4b71Sopenharmony_ci    ```ts
83e41f4b71Sopenharmony_ci    async loadPageOne(key: string){
84e41f4b71Sopenharmony_ci      if (key === "pageOne") {
85e41f4b71Sopenharmony_ci        let PageObj: ESObject = await import("../pages/PageOneLoader");
86e41f4b71Sopenharmony_ci        this.PageOneLoader = PageObj.PageOneLoader;
87e41f4b71Sopenharmony_ci      }
88e41f4b71Sopenharmony_ci    }
89e41f4b71Sopenharmony_ci    ```
90e41f4b71Sopenharmony_ci   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.
91e41f4b71Sopenharmony_ci    ```ts
92e41f4b71Sopenharmony_ci    private onEntryClick(): void {
93e41f4b71Sopenharmony_ci      try {
94e41f4b71Sopenharmony_ci        this.loadPageOne('pageOne');
95e41f4b71Sopenharmony_ci        this.pageInfos.clear();
96e41f4b71Sopenharmony_ci        this.pageInfos.pushPathByName('pageOne', '');
97e41f4b71Sopenharmony_ci        logger.info('DynamicImport Success');
98e41f4b71Sopenharmony_ci      } catch (error) {
99e41f4b71Sopenharmony_ci        logger.info('DynamicImport Fail');
100e41f4b71Sopenharmony_ci      }
101e41f4b71Sopenharmony_ci    }
102e41f4b71Sopenharmony_ci    ```
103e41f4b71Sopenharmony_ci   d. Trigger the initialized **PageOneLoader** function in **PageMap** to dynamically load the **PageOne** component.
104e41f4b71Sopenharmony_ci    ```ts
105e41f4b71Sopenharmony_ci    @Builder
106e41f4b71Sopenharmony_ci    PageMap(name: string) {
107e41f4b71Sopenharmony_ci      if (name === 'pageOne') {
108e41f4b71Sopenharmony_ci        this.PageOneLoader();
109e41f4b71Sopenharmony_ci      }
110e41f4b71Sopenharmony_ci    }
111e41f4b71Sopenharmony_ci    ```
112e41f4b71Sopenharmony_ciThe complete code of the **DynamicHome** home page is as follows:
113e41f4b71Sopenharmony_ci```ts
114e41f4b71Sopenharmony_ciimport router from '@ohos.router';
115e41f4b71Sopenharmony_ciimport { logger } from '../../ets/utils/Logger';
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci@Entry
118e41f4b71Sopenharmony_ci@Component
119e41f4b71Sopenharmony_cistruct DynamicHome {
120e41f4b71Sopenharmony_ci  @Provide('pathInfos') pageInfos: NavPathStack = new NavPathStack();
121e41f4b71Sopenharmony_ci  @State active: boolean = false;
122e41f4b71Sopenharmony_ci  @BuilderParam PageOneLoader: () => void;
123e41f4b71Sopenharmony_ci
124e41f4b71Sopenharmony_ci  @Builder
125e41f4b71Sopenharmony_ci  PageMap(name: string) {
126e41f4b71Sopenharmony_ci    if (name === 'pageOne') {
127e41f4b71Sopenharmony_ci      this.PageOneLoader();
128e41f4b71Sopenharmony_ci    }
129e41f4b71Sopenharmony_ci  }
130e41f4b71Sopenharmony_ci
131e41f4b71Sopenharmony_ci  build() {
132e41f4b71Sopenharmony_ci    Navigation(this.pageInfos) {
133e41f4b71Sopenharmony_ci      Column() {
134e41f4b71Sopenharmony_ci        Button('Back', { stateEffect: true, type: ButtonType.Capsule })
135e41f4b71Sopenharmony_ci          .width('80%')
136e41f4b71Sopenharmony_ci          .height(40)
137e41f4b71Sopenharmony_ci          .margin(20)
138e41f4b71Sopenharmony_ci          .onClick(() => {
139e41f4b71Sopenharmony_ci            router.back();
140e41f4b71Sopenharmony_ci          })
141e41f4b71Sopenharmony_ci        Button('PageOne-Dynamic', { stateEffect: true, type: ButtonType.Capsule })
142e41f4b71Sopenharmony_ci          .width('80%')
143e41f4b71Sopenharmony_ci          .height(40)
144e41f4b71Sopenharmony_ci          .margin(20)
145e41f4b71Sopenharmony_ci          .onClick(() => {
146e41f4b71Sopenharmony_ci            this.onEntryClick();
147e41f4b71Sopenharmony_ci          })
148e41f4b71Sopenharmony_ci      }
149e41f4b71Sopenharmony_ci    }.title('HOME').navDestination(this.PageMap)
150e41f4b71Sopenharmony_ci  }
151e41f4b71Sopenharmony_ci
152e41f4b71Sopenharmony_ci  async loadPageOne(key: String) {
153e41f4b71Sopenharmony_ci    if (key === "pageOne") {
154e41f4b71Sopenharmony_ci      let PageObj: ESObject = await import("../pages/PageOneLoader");
155e41f4b71Sopenharmony_ci      this.PageOneLoader = PageObj.PageOneLoader;
156e41f4b71Sopenharmony_ci    }
157e41f4b71Sopenharmony_ci  }
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci  // Trigger dynamic loading.
160e41f4b71Sopenharmony_ci  private onEntryClick(): void {
161e41f4b71Sopenharmony_ci    try {
162e41f4b71Sopenharmony_ci      this.loadPageOne('pageOne');
163e41f4b71Sopenharmony_ci      this.pageInfos.clear();
164e41f4b71Sopenharmony_ci      this.pageInfos.pushPathByName('pageOne', '');
165e41f4b71Sopenharmony_ci      logger.info('DynamicImport Success');
166e41f4b71Sopenharmony_ci    } catch (error) {
167e41f4b71Sopenharmony_ci      logger.info('DynamicImport Fail');
168e41f4b71Sopenharmony_ci    }
169e41f4b71Sopenharmony_ci  }
170e41f4b71Sopenharmony_ci}
171e41f4b71Sopenharmony_ci```
172e41f4b71Sopenharmony_ciIn 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