三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

HarmonyOS ArkWeb 系列之页面预连接与 DNS 预解析:prepareForPageLoad 加速首屏

HarmonyOS ArkWeb 系列之页面预连接与 DNS 预解析:prepareForPageLoad 加速首屏

文章目录

    • 大白话讲原理
    • 流程图
    • API 说明
    • 完整示例
      • 方案一:组件出现时预热
      • 方案二:上一页加载完后预热下一页(列表→详情场景)
      • 方案三:Ability onCreate 里预热(App 启动即预热)
    • preconnect 参数怎么选?
    • 注意事项

内嵌 Web 页面首屏慢,十有八九是网络耗时占大头。DNS 解析 + TCP 握手 + TLS 握手,加起来轻松超过 300ms。prepareForPageLoad让你在用户点击之前就把这些事提前做完。

大白话讲原理

正常流程:用户点击 → DNS 解析 → TCP 连接 → TLS 握手 → 发送请求 → 收到响应 → 渲染

用了预连接:App 启动或上一页加载完 →提前做 DNS + 建连→ 用户点击 → 直接发请求 → 渲染

省掉的那几百毫秒,用户感受非常明显。

流程图

API 说明

webview.WebviewController.prepareForPageLoad(url:string,// 要预热的目标 URLpreconnect:boolean,// true = DNS+TCP建连;false = 仅 DNS 解析numSockets:number// 预建连接数,最多 6 个):void

这是静态方法,不需要 Web 组件已经存在,可以在 Ability 的onCreate里就调用。

完整示例

方案一:组件出现时预热

import{webview}from'@kit.ArkWeb';@Entry@Componentstruct PreconnectPage{webviewController:webview.WebviewController=newwebview.WebviewController();privatetargetUrl:string='https://www.example.com';build(){Column(){Button('后退').onClick(()=>{if(this.webviewController.accessBackward()){this.webviewController.backward();}})Web({src:this.targetUrl,controller:this.webviewController}).onAppear(()=>{// 组件出现时立刻预连接目标 URL// 第二个参数 true = DNS 解析 + TCP 建连// 第三个参数 2 = 预建 2 个 socket(HTTP/2 下够用)webview.WebviewController.prepareForPageLoad(this.targetUrl,true,2);}).width('100%').layoutWeight(1)}.width('100%').height('100%')}}

方案二:上一页加载完后预热下一页(列表→详情场景)

import{webview}from'@kit.ArkWeb';@Entry@Componentstruct ListToDetailPage{listController:webview.WebviewController=newwebview.WebviewController();privatedetailUrl:string='https://www.example.com/detail/123';build(){Column(){Web({src:'https://www.example.com/list',controller:this.listController}).onPageEnd(()=>{// 列表页加载完后,提前预热详情页// 用户从列表点进详情时,连接早就建好了webview.WebviewController.prepareForPageLoad(this.detailUrl,true,3);console.info('详情页预连接已发起');}).width('100%').height('100%')}}}

方案三:Ability onCreate 里预热(App 启动即预热)

// EntryAbility.etsimport{AbilityConstant,UIAbility,Want}from'@kit.AbilityKit';import{webview}from'@kit.ArkWeb';exportdefaultclassEntryAbilityextendsUIAbility{onCreate(want:Want,launchParam:AbilityConstant.LaunchParam):void{// 提前初始化 Web 内核webview.WebviewController.initializeWebEngine();// 只做 DNS 预解析(false),不建 TCP 连接,开销最小webview.WebviewController.prepareForPageLoad('https://www.example.com',false,1);}}

preconnect 参数怎么选?

场景preconnectnumSockets
只是猜测用户可能访问false(仅 DNS)1
比较确定用户会访问true(DNS + 建连)2~3
非常确定且页面资源多true4~6

DNS 预解析开销极小,可以大方用。TCP 建连有资源消耗,对确定会打开的页面才用。

注意事项

  1. 静态方法,调用前不需要 Web 组件存在
  2. 预连接有时效性,长时间不用的连接会被关闭
  3. 不要对所有可能的 URL 都预连接,选最有可能被访问的 1~3 个
  4. 配合initializeWebEngine()提前初始化内核,效果更好
← 返回列表