DEV Community

Cover image for Dynamic loading
liu yang
liu yang

Posted on

Dynamic loading

Dynamic Import: Enhancing Loading Speed and Enabling Reflection

I. Technical Scenarios for Dynamic Import

Dynamic import is a powerful feature that allows modules to be loaded on - demand. It's particularly useful in the following scenarios:

  • When a statically imported module significantly slows down code loading but is rarely used or doesn't need to be used immediately.
  • When a statically imported module consumes a large amount of system memory but is rarely used.
  • When the imported module doesn't exist at load time and needs to be obtained asynchronously.
  • When the module specifier needs to be dynamically constructed, as static import only allows static specifiers.
  • When the imported module has side effects (code that runs directly in the module) that are only needed when certain conditions are triggered.

II. Business Expansion with Dynamic Import

Beyond conditional lazy loading, dynamic import also enables partial reflection capabilities. For example, a HAP can dynamically import a HAR package (harlibrary) and call its static member functions, member functions, and global methods.

Code Example

Calc.ets (Part of harlibrary)

export class Calc {
  public static staticAdd(a: number, b: number): number {
    let c = a + b;
    console.info('DynamicImport I am harlibrary in staticAdd, %d + %d = %d', a, b, c);
    return c;
  }

  public instanceAdd(a: number, b: number): number {
    let c = a + b;
    console.info('DynamicImport I am harlibrary in instanceAdd, %d + %d = %d', a, b, c);
    return c;
  }
}

export function addHarlibrary(a: number, b: number): number {
  let c = a + b;
  console.info('DynamicImport I am harlibrary in addHarlibrary, %d + %d = %d', a, b, c);
  return c;
}
Enter fullscreen mode Exit fullscreen mode

Index.ets (Part of harlibrary)

export { Calc, addHarlibrary } from './src/main/ets/utils/Calc'
Enter fullscreen mode Exit fullscreen mode

oh - package.json5 (Part of HAP)

"dependencies": {
  "harlibrary": "file:../harlibrary"
}
Enter fullscreen mode Exit fullscreen mode

Index.ets (Part of HAP)

import('harlibrary').then((ns: ESObject) => {
  ns.Calc.staticAdd(8, 9);
  let calc: ESObject = new ns.Calc();
  calc.instanceAdd(10, 11);
  ns.addHarlibrary(6, 7);

  // Reflection - based calls using class, method, and function names as strings
  let className = 'Calc';
  let methodName = 'instanceAdd';
  let staticMethod = 'staticAdd';
  let functionName = 'addHarlibrary';
  ns[className][staticMethod](12, 13);
  let calc1: ESObject = new ns[className]();
  calc1[methodName](14, 15);
  ns[functionName](16, 17);
});
Enter fullscreen mode Exit fullscreen mode

III. Dynamic Import Implementation

Dynamic import can be categorized into two types based on whether the input is a constant or a variable: dynamic import with constant expressions and dynamic import with variable expressions.

Supported Dynamic Import Specifications

Dynamic Import Scenario Detailed Classification Description
Local Project Module Dynamic import of module - internal file paths Path must start with ./ or ../
Local Project Module Dynamic import of HSP module names -
Local Project Module Dynamic import of HSP module file paths Only constant expressions are currently supported; variable expressions are not
Local Project Module Dynamic import of HAR module names -
Local Project Module Dynamic import of HAR module file paths Only constant expressions are currently supported; variable expressions are not
Remote Packages Dynamic import of remote HAR module names -
Remote Packages Dynamic import of ohpm package names -
API Dynamic import of @system.* -
API Dynamic import of @ohos.* -
API Dynamic import of @arkui - x.* -
Native Module Libraries Dynamic import of libNativeLibrary.so -

Note:

  • The module names used in all imports depend on the aliases in the dependencies section of the consumer's oh - package.json5.
  • It is recommended that the aliases for local modules in the consumer's dependencies be consistent with moduleName and packageName. moduleName refers to the name configured in the module.json5 of the dependent HSP/HAR, and packageName refers to the name configured in the oh - package.json5 of the dependent HSP/HAR.
  • Importing a module name actually imports the entry file of the module, which is generally index.ets/ts.

IV. Key Aspects of Dynamic Import Implementation

Dynamic Import with Constant Expressions

Dynamic import with constant expressions refers to scenarios where the input to dynamic import is a constant. The following example illustrates the typical usage of HAP referencing other modules or APIs.

Example 1: HAP Constant Dynamic Import of HAR Module Name

// HAR's Index.ets
export function add(a: number, b: number): number {
  let c = a + b;
  console.info('DynamicImport I am a HAR, %d + %d = %d', a, b, c);
  return c;
}

// HAP's src/main/ets/pages/Index.ets
import('myHar').then((ns: ESObject) => {
  console.info(ns.add(3, 5));
});

// HAP's oh-package.json5
"dependencies": {
  "myHar": "file:../myHar"
}
Enter fullscreen mode Exit fullscreen mode

Example 2: HAP Constant Dynamic Import of HAR Module File Path

// HAR's Index.ets
export function add(a: number, b: number): number {
  let c = a + b;
  console.info('DynamicImport I am a HAR, %d + %d = %d', a, b, c);
  return c;
}

// HAP's src/main/ets/pages/Index.ets
import('myHar/Index').then((ns: ESObject) => {
  console.info(ns.add(3, 5));
});

// HAP's oh-package.json5
"dependencies": {
  "myHar": "file:../myHar"
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.