HarmonyOS Web 场景性能优化指导
一、概述
在移动互联网时代,应用的页面渲染速度对于用户体验至关重要。相对于原生页面,Web 页面的性能存在多方面的技术挑战。本文以 HarmonyOS 的 ArkWeb 组件为基础,介绍了 Web 页面加载中的影响因素以及对应的优化方案。
二、Web 页面加载性能优化指导
(一)Web 页面加载流程
Web 页面加载包含网络连接、资源下载、DOM 解析、JavaScript 代码编译执行和渲染等关键环节,本文主要针对网络连接、资源下载和完整页面渲染这些关键节点的耗时进行优化。
预启动 Web 渲染进程:预启动 Web 渲染进程指用户可以在业务需要的 Web 页面启动前,加载一个空白的 Web 组件,在至少一个 Web 组件存活时,Web 渲染进程进程会一直存在,节省了用户后续启动 Web 组件拉起渲染进程的时间,加快页面加载速度。
预解析:预解析指预先对 DNS 进行解析,可以节省 DNS 解析的时间,从而优化 Web 的加载耗时。
预连接:预连接包含预解析的步骤,可以在用户请求页面之前提前进行 DNS 解析和 socket 连接建立,这样当用户真正请求页面时,服务器和浏览器之间已经建立好了连接,可以直接传输数据,减少了网络延迟,提升了页面加载速度。
预下载:预下载指在页面加载之前提前下载所需的资源,以避免在页面加载过程中资源下载导致的阻塞和耗时。通过预下载,可以在浏览器加载页面时,提前获取到所需的资源如图片、CSS 文件、JavaScript 文件等。通过提前下载这些资源,可以避免在页面加载时因为资源未加载完成而导致页面渲染延迟的情况发生。通过合理地使用预下载技术,用户在访问页面时可以更快地看到页面内容,提高整体性能,提升用户体验。
预渲染:预渲染指在后台对需要加载的页面进行预先渲染,提前完成整个页面加载的流程。当用户需要访问该页面时,可以直接切换至前台展示,实现页面“秒开”的效果。预渲染要求在进行 DOM 解析、JavaScript 执行和页面渲染之前,已经完成了所需资源的下载工作,否则可能会导致页面内容不完整或者渲染错误的情况。通过预渲染,可以显著减少用户等待页面加载的时间,特别是对于一些需要加载大量资源或者有复杂交互的页面。
预取 POST:预取 POST 指当即将加载的 Web 页面中存在 POST 请求且 POST 请求耗时较长时,可对 POST 请求进行预获取,消除等待 POST 请求数据下载完成的耗时,当用户真正发起 POST 请求时,进行拦截替换,加快页面加载速度,提高用户体验。
预编译 JavaScript 生成字节码缓存(Code Cache):该方案会将使用到的 JavaScript 文件编译成字节码并缓存到本地,在页面首次加载时节省编译时间。
资源拦截替换的 JavaScript 生成字节码缓存(Code Cache):该方案会将资源拦截替换场景下的 JavaScript 文件编译成字节码并缓存到本地,节省在页面非首次加载时的编译时间。
离线资源免拦截注入:在页面加载之前,离线资源免拦截注入会将需要使用的图片、样式表和脚本资源注入到内存缓存中,节省页面首次加载时的网络请求时间。
资源拦截替换加速:在原本的资源拦截替换接口基础上,资源拦截替换加速支持了 ArrayBuffer 格式的入参,开发者无需在应用侧进行 ArrayBuffer 到 String 格式的转换,可直接使用 ArrayBuffer 格式的数据进行拦截替换。
由于所有的关键点都是建立在预处理的思路上,因此如果用户实际并未打开预处理的 Web 页面,将会造成额外的资源消耗。各优化方法具体的效果、代价和适用场景的对比如下表所示。
(二)预启动 Web 渲染进程
原理介绍
此方案适用于 Web 页面启动场景。开发者需额外创建一个空白的 ArkWeb 组件,它虽不显示给用户,但会提前拉起渲染进程,且该进程在 Web 组件全部销毁前与应用侧全局共用,可节省后续组件加载时启动渲染进程的时间。不过,创建此组件会消耗约 200Mb 内存和算力。
建议在 Web 页面启动前(如应用冷启动或广告阶段)执行该方案,若冷启动无法进行,可在空闲时间启动。
(三)预解析和预连接优化
原理介绍 如下图所示,在应用启动和 UIAbility 的 onCreate 生命周期后,Web 组件才能进行初始化和运行。在 ArkWeb 组件运行阶段,会经过 onAppear、load、onPageBegin、onPageEnd 步骤。预解析、预连接优化适用于 Web 页面启动和跳转场景,例如,应用启动时需要加载 Web 首页。当开发者已经创建一个 ArkWeb 组件的实例后,可以选择不同时机对当前 ArkWeb 组件设置 URL 并进行预解析、预连接:
如下图中 a 节点所示,如果是应用首页,推荐在 ArkWeb 组件初始化创建后设置首页的 URL,进行预解析、预连接;
如下图中 b 节点所示,如果是应用内页面,推荐 ArkWeb 组件 onAppear 阶段设置当前页面的 URL,进行预解析、预连接;
如下图中 c 节点所示,当前页面完成加载后,可以设置用户下一步可能点击页面的 URL,进行预解析、预连接,推荐在 onPageEnd 及后续时机进行。
(四)预下载优化
原理介绍
适用于 Web 页面启动和跳转场景。在 ArkWeb 组件运行的onPageEnd
阶段,可设置 URL 提前下载页面所需资源,能消除资源下载耗时及对 DOM 解析和 JS 代码编译执行的阻塞耗时,但会消耗额外流量和内存,适合高频页面。预下载行为包括连接和资源下载,耗时可能达 700ms 以上,预下载完成后当前组件连接关闭,如需下一个页面预连接需显式调用接口。
(五)预渲染优化
原理介绍
预渲染优化适用于 Web 页面启动和跳转场景,例如,进入首页后,跳转到其他子页。与预连接、预下载不同的是,预渲染需要开发者额外创建一个新的 ArkWeb 组件,并在后台对其进行预渲染,此时该组件并不会立刻挂载到组件树上,即不会对用户呈现(组件状态为 Hidden 和 InActive),开发者可以在后续使用中按需动态挂载。
具体原理如下图所示,首先需要定义一个自定义组件封装 ArkWeb 组件,该 ArkWeb 组件被离线创建,被包含在一个无状态的节点 NodeContainer 中,并与相应的 NodeController 绑定。该 ArkWeb 组件在后台完成预渲染后,在需要展示该 ArkWeb 组件时,再通过 NodeController 将其挂载到 ViewTree 的 NodeContainer 中,即通过 NodeController 绑定到对应的 NodeContainer 组件。预渲染通用实现的步骤如下:
创建自定义 ArkWeb 组件:开发者需要根据实际场景创建封装一个自定义的 ArkWeb 组件,该 ArkWeb 组件被离线创建。
创建并绑定NodeController:实现 NodeController 接口,用于自定义节点的创建、显示、更新等操作的管理。并将对应的 NodeController 对象放入到容器中,等待调用。
绑定NodeContainer组件:将 NodeContainer 与 NodeController 进行绑定,实现动态组件页面显示。
(六)预取 POST 请求优化
原理介绍
预取 POST 请求适用于 Web 页面启动和跳转场景,当即将加载的 Web 页面中存在 POST 请求且 POST 请求耗时较长时,会导致页面加载时间增加,可以选择不同时机对 POST 请求进行预获取,消除等待 POST 请求数据下载完成的耗时,具体有以下两种场景可供参考:
如果是应用首页,推荐在 ArkWeb 组件创建后或者提前初始化 Web 内核后,对首页的 POST 请求进行预取,如 XComponent.onCreate()、自定义组件的生命周期函数 aboutToAppear()。
当前页面完成加载后,可以对用户下一步可能点击页面的 POST 请求进行预取,推荐在 Web 组件的生命周期函数 onPageEnd()及后续时机进行。
(七)预编译 JavaScript 生成字节码缓存(Code Cache)
原理介绍
预编译 JavaScript 生成字节码缓存适用于在页面加载之前提前将即将使用到的 JavaScript 文件编译成字节码并缓存到本地,在页面首次加载时节省编译时间。
开发者需要创建一个无需渲染的离线 Web 组件,用于进行预编译,在预编译结束后使用其他 Web 组件加载对应的业务网页。
(八)资源拦截替换的 JavaScript 生成字节码缓存(Code Cache)
原理介绍
对资源拦截替换场景下的 JavaScript 文件进行编译和缓存,节省非首次加载时的编译时间。
JS 资源编译执行流程
资源拦截替换后 JS 资源编译执行流程
Web 组件默认支持 HTTP 协议的 JavaScript 生成字节码缓存,也支持自定义协议的 JavaScript 生成字节码缓存,具体步骤如下:
开发者首先需要在 Web 组件运行前,向 Web 组件注册自定义协议。
其次需要拦截自定义协议的 JavaScript,设置 ResponseData 和 ResponseDataID。
(九)离线资源免拦截注入
原理介绍
在页面加载前,将图片、样式表和脚本资源注入内存缓存,节省首次加载的网络请求时间。
说明
开发者需创建一个无需渲染的离线 Web 组件,用于将资源注入到内存缓存中,使用其他 Web 组件加载对应的业务网页。
仅使用 HTTP 或 HTTPS 协议请求的资源可被注入进内存缓存。
内存缓存中的资源由内核自动管理,当注入的资源过多导致内存压力过大,内核自动释放未使用的资源,应避免注入大量资源到内存缓存中。
正常情况下,资源的有效期由提供的 Cache-Control 或 Expires 响应头控制其有效期,默认的有效期为 86400 秒,即 1 天。
资源的 MIMEType 通过提供的参数中的 Content-Type 响应头配置,Content-Type 需符合标准,否则无法正常使用,MODULE_JS 必须提供有效的 MIMEType,其他类型可不提供。
仅支持通过 HTML 中的标签加载。
如果业务网页中的 script 标签使用了 crossorigin 属性,则必须在接口的 responseHeaders 参数中设置 Cross-Origin 响应头的值为 anoymous 或 use-credentials。
当调用 webview.WebviewController.SetRenderProcessMode(web_webview.RenderProcessMode.MULTIPLE)接口后,应用会启动多渲染进程模式,此方案在此场景下不会生效。
单次调用最大支持注入 30 个资源,单个资源最大支持 10Mb。
(十)资源拦截替换加速
原理介绍
资源拦截替换加速在原本的资源拦截替换接口基础上新增支持了 ArrayBuffer 格式的入参,开发者无需在应用侧进行 ArrayBuffer 到 String 格式的转换,可直接使用 ArrayBuffer 格式的数据进行拦截替换。
三、总结
本文深入探讨了 Web 页面加载的原理和优化方法,为开发者提供了重要的指导和思路。在当今互联网时代,用户对网页加载速度和体验要求越来越高,因此页面加载优化成为开发者必须重视的一环。通过理解 Web 页面加载的原理,开发者可以更好地处理页面加载与优化的相关问题,提升应用的整体质量。
文中提供了预连接、预下载、预渲染、预取 POST、预编译等多种常见的优化方法,指导开发者优化 Web 页面的加载速度。这些方法可以有效提高应用流畅度、提升用户体验。
综上所述,Web 页面加载优化对于提升用户体验、提高网站性能、增加页面浏览量和提高转化率具有重要意义。开发者应该重视页面加载优化,不断探索和实践各种优化方法,以提升用户体验,实现商业目标。通过文章介绍的几种优化方法,开发者可以改善页面加载速度,提升用户体验,增加页面浏览量,提高应用的活跃度和用户粘性。只有不断优化页面加载速度,才能更好地满足用户需求,提升应用价值。
评论