harmony 鸿蒙Side Effects and Optimization of Module Loading
Side Effects and Optimization of Module Loading
Overview
When using ArkTS modularization, the process of loading and executing modules may introduce side effects. These side effects refer to additional behavior or state changes that occur when importing a module, beyond simply exporting functions or objects. Such behavior might affect other parts of the program, leading to unintended consequences such as unexpected top-level code execution, global state changes, prototype chain modifications, and undefined imported content.
Scenarios and Optimization Methods for Side Effects
Top-Level Code Execution in Modules
Scenario of Side Effects
When a module is imported, all top-level code within the module file is executed immediately, not just the exported parts. This means that even if only specific exports are needed, any code in the top-level scope will run, potentially causing side effects.
// module.ets
console.log("Module loaded!"); // The code is executed immediately upon import, which may cause side effects.
export const data = 1;
// main.ets
import { data } from './module' // When data is imported, the console.log file in module.ets is executed and output is generated.
console.log(data);
The output is as follows:
Module loaded!
1
Side effects produced
Even though only data is required, console.log(“Module loaded!”) still runs, causing the unexpected output of “Module loaded!” in addition to the value of data.
Optimized methods
Optimization method 1: Remove the top-level code and export only the required content to avoid unnecessary code execution.
// module.ets
export const data = 1;
// main.ets
import { data } from './module'
console.log(data);
The output is as follows:
1
Optimization method 2: Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading.
// module.ets
export function initialize() {
console.log("Module loaded!");
}
export const data = 1;
// main.ets
import { data } from './module'
console.log(data);
The output is as follows:
1
Modifying Global Objects
Scenario of side effects
The top-level code or imported modules may directly manipulate global variables, thereby changing the global state and causing side effects.
// module.ets
export let data1 = "data from module"
globalThis.someGlobalVar = 100; // The global state is changed.
// sideEffectModule.ets
export let data2 = "data from side effect module"
globalThis.someGlobalVar = 200; // The global state is changed.
// moduleUseGlobalVar.ets
import { data1 } from './module' // The expected value of the global variable someGlobalVar is 100.
export function useGlobalVar() {
console.log(data1);
console.log(globalThis.someGlobalVar); // The value of someGlobalVar is changed to 200 because the sideEffectModule module is loaded to main.ets.
}
// main.ets (entry point)
import { data1 } from "./module" // The value of the global variable someGlobalVar is changed to 100.
import { data2 } from "./sideEffectModule" // The value of the global variable someGlobalVar is changed to 200.
import { useGlobalVar } from './moduleUseGlobalVar'
useGlobalVar();
function maybeNotCalledAtAll() {
console.log(data1);
console.log(data2);
}
The output is as follows:
data from module
200
Side effects produced
Modules directly change the value of the global variable globalThis.someGlobalVar, affecting other modules or code that use this variable.
Optimized methods
Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading.
// module.ets
export let data1 = "data from module"
export function changeGlobalVar() {
globalThis.someGlobalVar = 100;
}
// sideEffectModule.ets
export let data2 = "data from side effect module"
export function changeGlobalVar() {
globalThis.someGlobalVar = 200;
}
// moduleUseGlobalVar.ets
import { data1, changeGlobalVar } from './module'
export function useGlobalVar() {
console.log(data1);
changeGlobalVar(); // Execute the code when needed, not upon module loading.
console.log(globalThis.someGlobalVar);
}
// main.ets (entry point)
import { data1 } from "./module"
import { data2 } from "./sideEffectModule"
import { useGlobalVar } from './moduleUseGlobalVar'
useGlobalVar();
function maybeNotCalledAtAll() {
console.log(data1);
console.log(data2);
}
The output is as follows:
data from module
100
Modifying State Variables of Application-level ArkUI Components
Scenario of side effects
The top-level code or imported modules may directly modify the state variables of application-level ArkUI components, thereby changing the global state and causing side effects.
// module.ets
export let data = "data from module"
AppStorage.setOrCreate("SomeAppStorageVar", 200); // The global UI state of the application is changed.
// Index.ets
import { data } from "./module" // SomeAppStorageVar in AppStorage is changed to 200.
@Entry
@Component
struct Index {
// The expected value is 100. However, the value has been changed to 200 due to module import.
@StorageLink("SomeAppStorageVar") message: number = 100;
build() {
Row() {
Column() {
Text("test" + this.message)
.fontSize(50)
}
.width("100%")
}
.height("100%")
}
}
function maybeNotCalledAtAll() {
console.log(data);
}
The following content is displayed:
test200
Side effects produced
Modules directly change the value of SomeAppStorageVar in AppStorage, affecting other modules or code that use this variable.
For more information on modifying ArkUI component state variables, see State Management Overview.
Optimized methods
Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading.
// module.ets
export let data = "data from module"
export function initialize() {
AppStorage.setOrCreate("SomeAppStorageVar", 200);
}
// Index.ets
import { data } from "./module"
@Entry
@Component
struct Index {
@StorageLink("SomeAppStorageVar") message: number = 100;
build() {
Row() {
Column() {
Text("test" + this.message)
.fontSize(50)
}
.width("100%")
}
.height("100%")
}
}
function maybeNotCalledAtAll() {
console.log(data);
}
The following content is displayed:
test100
Modifying Built-in Global Variables or Prototype Chains (Modifying Object Prototypes or Built-in Methods Is Forbidden in ArkTS)
Scenario of side effects
Some third-party libraries or frameworks may modify built-in global objects or prototype chains to support modern JavaScript features in older browsers or runtime environments. This may affect the execution of other code.
// modifyPrototype.ts
export let data = "data from modifyPrototype"
Array.prototype.includes = function (value) {
return this.indexOf(value) !== -1;
};
// main.ets
import { data } from "./modifyPrototype" // The prototype chain of the array is modified.
let arr = [1, 2, 3, 4];
console.log("arr.includes(1) = " + arr.includes(1)); // The Array.prototype.includes method in modifyPrototype.ts is called.
function maybeNotCalledAtAll() {
console.log(data);
}
Side effects produced
Modifying built-in global objects or prototype chains affects the execution of other code.
Optimized methods
When importing third-party libraries that may modify built-in global objects or prototype chains, ensure that the behavior of the third-party library is as expected.
Circular Dependencies
Scenario of side effects
ArkTS modularization supports circular dependencies, where module A depends on module B, and module B depends on module A. In such cases, some imported modules may not be fully loaded, leading to abnormal behavior and unintended side effects during execution.
// a.ets
import { b } from "./b"
console.log('Module A: ', b);
export const a = 'A';
// b.ets
import { a } from "./a"
console.log('Module B: ', a);
export const b = 'B';
The output is as follows:
Error message: a is not initialized
Stacktrace:
at func_main_0 (b.ets:2:27)
Side effects produced
Due to mutual dependencies between modules, the execution order of modules may result in undefined exports, affecting the logic flow of the code.
Optimized methods
Avoid circular dependencies between modules whenever possible, and ensure that the loading order of modules is clear and controllable to prevent unexpected side effects. You can use @security/no-cycle when detecting circular dependencies.
Lazy Import Changing the Module Execution Sequence and Leading to Undefined Global Variables
Scenario of side effects
The Lazy Import feature allows modules to be loaded on-demand during the application runtime, rather than during the cold start phase, thereby reducing the cold start time. However, this also changes the execution sequence of modules.
// module.ets
export let data = "data from module"
globalThis.someGlobalVar = 100;
// moduleUseGlobalVar.ets
import lazy { data } from "./module"
console.log(globalThis.someGlobalVar); // The module is not executed due to lazy import. The value of someGlobalVar is undefined.
console.log(data); // During the value of the variable, the module is executed and the value of someGlobalVar changes to 100.
The output is as follows:
undefined
data from module
Side effects produced
Using the lazy import feature delays the execution of modules until they are needed. Modifications to global variables within these modules are also delayed, potentially leading to unexpected results.
Optimized methods
Encapsulate code that may cause side effects within functions or methods, and execute the code only when needed, rather than upon module loading.
// module.ets
export let data = "data from module"
export function initialize() {
globalThis.someGlobalVar = 100; // Delay the execution until the function is called.
}
// moduleUseGlobalVar.ets
import lazy { data, initialize } from "./module"
initialize(); // Execute the initialization function to initialize someGlobalVar.
console.log(globalThis.someGlobalVar); // someGlobalVar will have the expected value.
console.log(data);
The output is as follows:
100
data from module
你可能感兴趣的鸿蒙文章
harmony 鸿蒙Configuring arkOptions in build-profile.json5
harmony 鸿蒙Ark Bytecode File Format
harmony 鸿蒙Naming Conventions for Ark Bytecode Functions
harmony 鸿蒙Ark Bytecode Fundamentals
harmony 鸿蒙Overview of Ark Bytecode
- 所属分类: 后端技术
- 本文标签:
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦