As the functionality of applications continues to expand, the time required for cold start has significantly increased, primarily due to the loading of a large number of modules during the initial startup phase, many of which contain redundant files that are not actually executed. This situation not only delays the application's initialization process but also results in ineffective resource occupation. It is imperative to take measures to streamline the loading process, eliminate the execution of unnecessary files, optimize cold start performance, and ensure the smoothness of the user experience.
Note
Lazy loading functionality is supported starting from API version 12.
Developers must configure "compatibleSdkVersionStage": "beta3" in the project to use the lazy import syntax on API 12; otherwise, the compilation will fail.
Features
The lazy loading feature allows pending files to not be loaded during the cold start phase. Instead, these files are only loaded when the application actually needs them during runtime, thus reducing the time required for the cold start.
Usage
Developers can use tools like Trace or logging to identify files that were not actually called during the cold start. By analyzing this data, developers can accurately determine a list of files that do not need to be preloaded during the startup phase. For the call points of these files, the lazy attribute can be directly added. However, it should be noted that subsequent loading is done synchronously, which may block task execution (for example, if a click task triggers lazy loading, the runtime will execute the files not loaded during cold start, thereby increasing the time required).
Therefore, whether to use lazy loading needs to be assessed by the developer themselves.
Describe
Developers are not recommended to blindly increase the use of lazy, as it may increase the recognition overhead during both compilation and runtime.
Scene Behavior Analysis
Use lazy-import for deferred loading.
// main.ets
import lazy { a } from "./mod1"; // "mod1" Not executed
import { c } from "./mod2"; // "mod2" execute
// ...
console.info("main executed");
while (false) {
let xx = a;
}
// mod1.ets
export let a = "mod1 executed"
console.info(a);
// mod2.ets
export let c = "mod2 executed"
console.info(c);
The result is as follows:
mod2 executed
main executed
Reference both lazy-import and native import for the same module.
// main.ets
import lazy { a } from "./mod1"; // "mod1" Not executed
import { c } from "./mod2"; // "mod2" executed
import { b } from "./mod1"; // "mod1" executed
// ...
console.info("main executed");
while (false) {
let xx = a;
}
// mod1.ets
export let a = "mod1 a executed"
console.info(a);
export let b = "mod1 b executed"
console.info(b);
// mod2.ets
export let c = "mod2 c executed"
console.info(c);
The result is as follows:
mod2 c executed
mod1 a executed
mod1 b executed
main executed
If the lazy keyword is deleted in main.ets, the order of execution is as follows:
mod1 a executed
mod1 b executed
mod2 c executed
main executed
Syntax specifications
lazy-import supports the following commands:
grammar ModuleRequest ImportName LocalName Whether API12 supports lazy loading
import lazy { x } from “mod”; “mod” “x” “x” support
import lazy { x as v } from “mod”; “mod” “x” “v” support
Lazy loading of shared modules or the inclusion of shared modules within a dependency path.
Lazy loading is still valid for shared modules, see the Shared Module Development Guide for usage restrictions.
Examples of errors
The following will cause a compilation error.
export lazy var v; //Compiler Error Message: An application compilation error is reported
export lazy default function f(){}; // Compiler Error Message: An application compilation error is reported
export lazy default function(){}; // Compiler Error Message: An application compilation error is reported
export lazy default 42; // Compiler Error Message: An application compilation error is reported
export lazy { x }; // Compiler Error Message: An application compilation error is reported
export lazy { x as v }; // Compiler Error Message: An application compilation error is reported
export lazy { x } from "mod"; // Compiler Error Message: An application compilation error is reported
export lazy { x as v } from "mod"; // Compiler Error Message: An application compilation error is reported
export lazy * from "mod"; // Compiler Error Message: An application compilation error is reported
import lazy v from "mod"; // Compiler Error Message: An application compilation error is reported
import lazy * as ns from "mod"; // Compiler Error Message: An application compilation error is reported
Using the type keyword together with the keyword will result in an error.
import lazy type { obj } from "./mod"; // No, the compiler and application compilation error is reported
import type lazy { obj } from "./mod"; // No, the compiler and application compilation error is reported
Not recommended
In the same ets file, the dependent module markup that expects lazy loading is incomplete.
Incomplete tagging will result in lazy loading invalidation and increase the overhead of identifying lazy loads.
// main.ets
import lazy { a } from "./mod1"; // Get the A object from inside "mod1" and mark it as lazy loaded
import { c } from "./mod2";
import { b } from "./mod1"; // Get the attributes in "mod1" again, "mod1" is not marked lazy, and "mod1" is executed by default
// ...
In the same ETS file, lazy loading variables are not used and exported again, lazy loading variables are not supported to be re-exported.
The variable c exported in this way is not used in B.ets, and the file B.ets does not trigger execution. When variable a is used in file A.ets, the variable is not initialized and a js exception is thrown.
// A.ets
import { c } from "./B";
console.info(c);
// B.ets
import lazy { c } from "./C"; // Get the A object from inside "mod1" and mark it as lazy loaded
export { c }
// C.ets
function c(){};
export { c }
Result:
ReferenceError: a is not initaliized
at func_main_0 (A.ets:2:1)
// A_ns.ets
import * as ns from "./B";
console.info(ns.c);
// B.ets
import lazy { c } from "./C"; // Get the A object from inside "mod1" and mark it as lazy loaded
export { c }
// C.ets
function c(){};
export { c }
Result:
ReferenceError: module environment is undefined
at func_main_0 (A_ns.js:2:1)
Lazy-import lazy loading kit is not supported.
Developers need to assess the impact of using lazy loading.
Side-effects that do not depend on the execution of the module (such as initializing global variables, mounting globalThis, etc.).
When using export objects, the time taken to trigger lazy loading leads to the deterioration of the functionality of the corresponding feature.
A bug caused by the use of the lazy feature causing the module to not be executed.
Top comments (0)