• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Lazy Import
2
3As applications evolve with more features, the time required for cold start increases significantly. The main reason is that numerous modules that are not actually executed are loaded during the initial startup. This not only prolongs application initialization but also leads to invalid resource utilization. To address this, it is crucial to streamline the loading process by eliminating non-essential file executions to optimize cold start performance and ensure a smooth user experience.
4
5> **NOTE**
6>
7> - The lazy import feature is supported since API version 12.
8>
9> - To use the lazy import syntax on API version 12, you must configure **"compatibleSdkVersionStage": "beta3"** in the project. Otherwise, the compilation fails. For details, see [Project-level build-profile.json5 File](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide-hvigor-build-profile-V5#section511142752919).
10> - For projects with API versions later than 12, you can directly use the **lazy import** syntax without any other configuration.
11
12
13## Features
14
15The lazy import feature prevents files from being loaded during the cold start phase. Instead, they are loaded on demand as the program runs, which helps to reduce cold start time.
16
17## Usage
18
19You can use <!--Del-->[<!--DelEnd-->Trace<!--Del-->](../performance/common-trace-using-instructions.md)<!--DelEnd--> or logs to identify files that are not actually called during cold start.<!--RP1--> For details about the analysis method, see [Lazy Import](../performance/Lazy-Import-Instructions.md).<!--RP1End--> By analyzing the data, you can accurately identify the list of files that do not need to be preloaded during startup and add **lazy** tags at the call points of these files. However, it is important to note that subsequent loading is synchronous and may block task execution. (For example, if a click task triggers a lazy import, the runtime will execute the files not loaded during the cold start, thereby increasing latency.) Therefore, you need to evaluate whether to use the **lazy** flag.
20
21> **NOTE**
22>
23> You are not advised to blindly add **lazy** flags, as this can also increase the overhead of identification during compilation and runtime.
24
25## Scenario Behavior Analysis
26
27- Use lazy-import for deferred loading.
28
29    ```typescript
30        // main.ets
31        import lazy { a } from "./mod1";    // "mod1" is not executed.
32        import { c } from "./mod2";         // "mod2" is executed.
33
34        // ...
35
36        console.info("main executed");
37        while (false) {
38            let xx = a;
39        }
40
41        // mod1.ets
42        export let a = "mod1 executed"
43        console.info(a);
44
45        // mod2.ets
46        export let c = "mod2 executed"
47        console.info(c);
48
49    ```
50
51    The execution result is as follows:
52
53    ```typescript
54        mod2 executed
55        main executed
56    ```
57
58- Use both lazy-import and native import for the same module.
59
60    ```typescript
61        // main.ets
62        import lazy { a } from "./mod1";    // "mod1" is not executed.
63        import { c } from "./mod2";         // "mod2" is executed.
64        import { b } from "./mod1";         // "mod1" is executed.
65
66        // ...
67
68        console.info("main executed");
69        while (false) {
70            let xx = a;
71        }
72
73        // mod1.ets
74        export let a = "mod1 a executed"
75        console.info(a);
76
77        export let b = "mod1 b executed"
78        console.info(b);
79
80        // mod2.ets
81        export let c = "mod2 c executed"
82        console.info(c);
83
84    ```
85
86    The execution result is as follows:
87
88    ```typescript
89        mod2 c executed
90        mod1 a executed
91        mod1 b executed
92        main executed
93    ```
94
95    If the keyword **lazy** is deleted from the **main.ets** file, the execution sequence is as follows:
96
97    ```typescript
98        mod1 a executed
99        mod1 b executed
100        mod2 c executed
101        main executed
102    ```
103
104## Syntax Specifications and Supported Versions
105
106- The lazy import feature supports the following syntax:
107
108| Syntax                                           | ModuleRequest  | ImportName | LocalName   | Supported API Version|
109|:----------------------------------------------|:---------------|:-----------|:------------|:-----------|
110| import lazy { x } from "mod";                 | "mod"          | "x"        | "x"         | API 12      |
111| import lazy { x as v } from "mod";            | "mod"          | "x"        | "v"         | API 12      |
112| import lazy x from "mod";                     | "mod"          | "default"  | "x"         | API 18      |
113| import lazy { KitClass } from "@kit.SomeKit"; | "@kit.SomeKit" | "KitClass" | "KitClass"  | API 18      |
114
115- Lazy importing of shared modules or modules within a dependency path that includes shared modules
116    Lazy import remains effective for shared modules. For details about the constraints, see [Shared Module](../arkts-utils/arkts-sendable-module.md).
117
118### Incorrect Example
119
120The following syntax will cause compilation errors:
121
122```typescript
123    export lazy var v;                    // The compiler reports an application compilation error.
124    export lazy default function f(){};   // The compiler reports an application compilation error.
125    export lazy default function(){};     // The compiler reports an application compilation error.
126    export lazy default 42;               // The compiler reports an application compilation error.
127    export lazy { x };                    // The compiler reports an application compilation error.
128    export lazy { x as v };               // The compiler reports an application compilation error.
129    export lazy { x } from "mod";         // The compiler reports an application compilation error.
130    export lazy { x as v } from "mod";    // The compiler reports an application compilation error.
131    export lazy * from "mod";             // The compiler reports an application compilation error.
132
133    import lazy * as ns from "mod";            // The compiler reports an application compilation error.
134    import lazy KitClass from "@kit.SomeKit"   // The compiler reports an application compilation error.
135    impott lazy * as MyKit from "@kit.SomeKit" // The compiler reports an application compilation error.
136```
137
138If the **type** keyword is added to the syntax, a compilation error is reported.
139
140```typescript
141    import lazy type { obj } from "./mod";    // Not supported. The compiler reports an application compilation error.
142    import type lazy { obj } from "./mod";    // Not supported. The compiler reports an application compilation error.
143
144```
145
146### Syntax Not Recommended
147
148- In the same .ets file, the expected lazy-loaded dependency modules are not fully marked.
149
150    Incomplete marking will cause lazy loading to fail and increase the overhead of identifying lazy-loaded modules.
151    ```typescript
152        // main.ets
153        import lazy { a } from "./mod1";    // Obtain the object a from "mod1" and add the lazy flag.
154        import { c } from "./mod2";
155        import { b } from "./mod1";         // Obtain the attributes in "mod1". This syntax is not added with the lazy flag, so "mod1" is executed by default.
156
157        // ...
158    ```
159- In the same.ets file, re-exporting unused lazy-loaded variables is not supported. To identify and resolve such issues, you can enable the **reExportCheckMode** switch in the project-level **build-profile.json5** file to perform a scan and check.
160    ```typescript
161        // build-profile.json5
162        "arkOptions":{
163            "reExportCheckMode":"compatible"
164        }
165    ```
166
167    > **NOTE**
168    >
169    > - For the following scenario, whether to intercept and report errors during compilation: Variables imported using lazy import are re-exported within the same file.
170    > - **noCheck** (default value): No check is performed, and no error is reported.
171    > - **compatible**: A warning is reported.
172    > - **strict**: An error is reported.
173    > - This field is supported since DevEco Studio 5.0.13.200.
174
175    The variable **c** is not used in **B.ets**, so **B.ets** does not trigger execution. When **c** is used in **A.ets**, it is not initialized, resulting in a JavaScript exception.
176    ```typescript
177        // A.ets
178        import { c } from "./B";
179        console.info(c);
180
181        // B.ets
182        import lazy { c } from "./C";    // Obtain the object c from "C" and add the lazy flag.
183        export { c }
184
185        // C.ets
186        let c = "c";
187        export { c }
188    ```
189    Result:
190    ```typescript
191        ReferenceError: c is not initialized
192             at func_main_0 (A.ets:2:13)
193    ```
194
195    ```typescript
196        // A_ns.ets
197        import * as ns from "./B";
198        console.info(ns.c);
199
200        // B.ets
201        import lazy { c } from "./C";    // Obtain the object c from "C" and add the lazy flag.
202        export { c }
203
204        // C.ets
205        let c = "c";
206        export { c }
207    ```
208    Result:
209    ```typescript
210    ReferenceError: module environment is undefined
211        at func_main_0 (A_ns.js:2:13)
212    ```
213
214- You need to evaluate the possible impact of lazy imports.
215
216  - Side effects that are independent of the module's execution (such as initializing global variables and mounting **globalThis**). For details, see [Side Effects and Optimization of Module Loading](./arkts-module-side-effects.md).
217  - Negative impact on the functionality of features due to the delay caused by triggering lazy imports when using exported objects.
218  - Using the lazy import feature can cause modules to not execute, thereby triggering bugs.
219
220<!--no_check-->