文章目录
-
- 大白话讲原理
- 流程图
- 核心代码
-
- DynamicComponent.ets — 组件创建与管理
- BusinessWebview.ets — 业务 Web 组件定义
- 业务页面 — 使用预创建组件
- 注意事项
前面讲的预连接、预获取,都是在网络层面优化。但 Web 组件本身的初始化也需要时间——创建内核、解析 HTML、布局渲染。动态组件预创建让你提前把 Web 实例准备好,用户打开时直接展示已渲染的内容。
大白话讲原理
想象一下餐厅备餐:
- 没有预创建:顾客点餐 → 厨师开始备料 → 烹饪 → 上菜(等很久)
- 有预创建:提前备好菜 → 顾客点餐 → 直接上菜
动态组件预创建就是让 Web 实例在"后台"默默初始化,等用户需要时,把已经准备好的实例"端上去"显示。
流程图

核心代码
DynamicComponent.ets — 组件创建与管理
// DynamicComponent.ets
import { webview } from '@kit.ArkWeb';
import { NodeController, BuilderNode, FrameNode, UIContext } from '@kit.ArkUI';
export interface BuilderData {
url: string;
controller: webview.WebviewController;
context: UIContext;
}
// 存储预创建的节点
const preloadNodeMap = new Map<string, BuilderNode<BuilderData[]>>();
export class WebNodeController extends NodeController {
private builderNode: BuilderNode<BuilderData[]> | null = null;
constructor(node: BuilderNode<BuilderData[]>) {
super();
this.builderNode = node;
}
makeNode(uiContext: UIContext): FrameNode | null {
return this.builderNode?.getFrameNode() ?? null;
}
}
// 预创建 Web 实例(后台)
export function initWebComponent(
url: string,
webBuilder: WrappedBuilder<BuilderData[]>,
uiContext: UIContext
): void {
if (preloadNodeMap.has(url)) return; // 已预创建,不重复
const controller = new webview.WebviewController();
const builderNode = new BuilderNode<BuilderData[]>(uiContext);
builderNode.build(webBuilder, { url, controller, context: uiContext });
preloadNodeMap.set(url, builderNode);
}
// 获取预创建的 NodeController
export function getPreloadNodeController(url: string): WebNodeController | null {
const node = preloadNodeMap.get(url);
return node ? new WebNodeController(node) : null;
}
BusinessWebview.ets — 业务 Web 组件定义
// BusinessWebview.ets
import { BuilderData } from './DynamicComponent';
@Builder
function webBuilder(data: BuilderData) {
Web({ src: data.url, controller: data.controller })
.cacheMode(CacheMode.Default)
}
export const businessWebview = wrapBuilder<BuilderData[]>(webBuilder);
业务页面 — 使用预创建组件
// Index.ets
import { webview } from '@kit.ArkWeb';
import { initWebComponent, getPreloadNodeController, WebNodeController } from './DynamicComponent';
import { businessWebview } from './BusinessWebview';
@Entry
@Component
struct BusinessPage {
@State nodeController: WebNodeController | null = null;
private targetUrl: string = 'https://www.example.com';
aboutToAppear(): void {
// 确保预创建完成
initWebComponent(this.targetUrl, businessWebview, this.getUIContext());
// 获取预创建节点
this.nodeController = getPreloadNodeController(this.targetUrl);
}
build() {
Column() {
if (this.nodeController) {
// 挂载预创建的 Web 实例,直接显示已渲染内容
NodeContainer(this.nodeController)
.width('100%')
.height('100%')
} else {
// 降级:正常创建
Web({ src: this.targetUrl, controller: new webview.WebviewController() })
.width('100%')
.height('100%')
}
}
.width('100%')
.height('100%')
}
}






