欢迎光临
我们一直在努力

HarmonyOS ArkWeb 系列之动态组件预创建:提前准备好 Web 实例,打开即渲染

文章目录

    • 大白话讲原理
    • 流程图
    • 核心代码
      • 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%')
}
}

注意事项

  • BuilderNode 依赖 UIContext,必须在 onWindowStageCreate 之后才能创建
  • 预创建的组件持续占用内存,不再需要时应及时释放
  • 同一 URL 只预创建一次,避免重复创建浪费资源
  • 后台加载的页面不可见,不会触发 onPageVisible
  • 赞(0)
    未经允许不得转载:171主机测评 » HarmonyOS ArkWeb 系列之动态组件预创建:提前准备好 Web 实例,打开即渲染
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址