# Web加载网页性能提升方式与使用场景总结

#### 问题现象

Web组件加载网页时，如何定位加载性能瓶颈，以及优化网页加载性能的方式有哪些？这些性能提升方式提升效果如何？适用于哪些场景？

#### 背景知识

*   Web加载完成时延是指从页面请求开始到页面视口内容加载完成的耗时，可通过使用DevTools分析耗时区域，定位加载性能瓶颈。
*   Web加载性能优化中讲解了多种Web加载性能优化方式。

#### 解决方案

想要提升Web组件加载网页性能，提升网页加载速度，首先需要了解Web组件加载网页流程：

加载网页时，容易出现耗时的点有：

*   网络连接：解析url、建立TCP连接(三次握手)存在耗时。
*   资源加载：解析过程中遇到图片、CSS、JS等资源，都会发起请求，等待服务端响应，存在网络请求过多、服务器响应慢、无强依赖关系接口串行请求等耗时情况。
*   JS编译与执行：执行JS代码前需要对JS资源进行编译和解析，JS代码量大或逻辑复杂时，会消耗大量解析和编译时间，阻塞页面渲染。

提升Web组件加载网页性能思路：定位加载耗时瓶颈点->针对加载耗时瓶颈点进行优化。

定位加载耗时瓶颈点：

可参考使用DevTools分析耗时区域DevTools->Performance工具进行耗时分析。

1.  使用DevTools -> Performance选项卡中Record and reload录制Trace。
    
2.  录制Trace后，Performance提供了多个泳道进行性能分析数据，常用泳道如下图所示。
    
    *   Main（主要）泳道：显示主线程上的任务活动情况，包括脚本执行、样式计算、布局和绘制等。
    *   Network（网络）泳道：显示页面在加载过程中发出的所有网络请求，帮助开发者分析页面加载性能，找出加载缓慢的资源以便进行优化。
    *   Frame（帧）泳道：显示每一帧的渲染情况，包括帧率与渲染时间，可以检测到页面中的卡顿和掉帧现象。
    *   Animation（动画）泳道：显示动画的执行情况。
3.  关注Network泳道中带“红色三角标”阻塞请求、串行请求、耗时较长的请求等，可在该泳道中分析资源加载耗时情况。
    
4.  关注Main泳道带“红色三角标”长任务，长任务会阻塞UI渲染，导致页面白屏或显示未渲染完成的内容。同时关注火焰图顶层宽度越大该活动越可能存在性能问题。可在该泳道分析JS编译与执行、DOM解析等耗时情况。
    

加载性能优化：

1.  通过Performance分析性能瓶颈点之后，可针对瓶颈点进行加载性能优化，系统提供了很多性能优化方式，包含：预启动Web渲染进程、预解析和预连接、预下载、预渲染、预取POST请求、预编译JavaScript生成字节码缓存（Code Cache）、资源拦截替换的JavaScript生成字节码缓存（Code Cache）、离线资源免拦截注入、资源拦截替换加速、JSBridge优化解决方案、同层渲染。这些能力的使用场景及效果：
    
    *   针对Web组件渲染进程性能优化：
        
        | 优化方案 | 原理 | 效果及收益 | 适用场景 | 对应用影响 |
        | --- | --- | --- | --- | --- |
        | 预启动Web渲染进程 | 提前创建空白Web组件保活渲染进程。 | 节省启动Web组件拉起渲染进程的时间。 收益：低。 | 存在高概率访问页面。 | 额外的内存、算力。 |
        
    *   针对网络连接耗时优化：
        
        | 优化方案 | 原理 | 效果及收益 | 适用场景 | 对应用影响 |
        | --- | --- | --- | --- | --- |
        | 预解析和预连接 | 提前完成DNS解析和TCP连接建立。 | 节省连接、解析url的时间。 收益：低。 | 中高概率页面（如首页）。 | 网络资源消耗（可能建立未用连接）。 |
        
    *   针对资源下载耗时优化：
        
        | 优化方案 | 原理 | 效果及收益 | 适用场景 | 对应用影响 |
        | --- | --- | --- | --- | --- |
        | 预下载 | 提前下载页面资源（CSS/JS/图片）。 | 节省页面资源下载的时间。 收益：中至高。 | 高频访问页面。 | 额外的网络连接、下载、存储资源。 |
        | 预渲染 | 提前后台完成完整页面渲染。 | 节省网页资源下载，渲染等时间。 收益：高。 | 超高概率跳转页（如首页→子页）。 | 额外的网络连接、下载、存储和渲染消耗。 |
        | 预取POST请求 | 对于耗时较长POST，提前请求获取数据。 | 节省等待POST请求数据下载完成的时间。 收益：低至中。 | 含耗时POST请求的页面。 | 额外的网络连接、下载、存储资源。 |
        
    *   针对JS编译与执行耗时优化：
        
        | 优化方案 | 原理 | 效果及收益 | 适用场景 | 对应用影响 |
        | --- | --- | --- | --- | --- |
        | 预编译JavaScript生成字节码缓存 | 预编译JS生成字节码缓存。 | 节省首次加载时编译时间。 收益：中至高。 | 页面存在HTTP/HTTPS协议JS。 | 额外的存储资源。 |
        | 资源拦截替换的JavaScript生成字节码缓存 | 拦截网络JS资源替换为本地JS资源并生成本地字节码缓存。 | 节省JS在页面非首次加载时编译时间。 收益：低至中。 | 页面存在HTTP/HTTPS协议JS。 | 额外的存储资源。 |
        | 离线资源免拦截注入 | 将资源预注入内存缓存。 | 节省资源注入内存缓存，首次加载的网络请求时间。 收益：中至高。 | 适用网页在线资源替换加速。 | 额外的存储资源。 |
        | 资源拦截替换加速 | 支持ArrayBuffer直传避免数据格式转换。 | 节省Web组件内部数据转换和传输时间。 收益：低。 | ArrayBuffer格式的数据传输。 | - |
        
    *   针对UI阻塞、渲染耗时优化：
        
        | 优化方案 | 原理 | 效果及收益 | 适用场景 | 对应用影响 |
        | --- | --- | --- | --- | --- |
        | JSBridge优化解决方案 | 减少ArkTS环境切换频率，允许回调在非UI线程上报，避免UI阻塞。 | 避免UI阻塞。 收益：低至中。 | 高频JS与Native通信场景。 | 开发复杂度高。 |
        | 同层渲染 | 将位于同一个图层的元素一起渲染，减少重绘与重排次数，提高页面的渲染效率。 | 降低渲染耗时。 收益：低至中。 | 有输入框、视频场景的复杂页面。 | 开发复杂度高。 |
        
    
    上述Web加载性能优化方案具体实现方式可点击对应超链接跳转查看。
    
2.  除了使用Web组件提供的优化方式，网页自身也可进行加载速率优化，优化方式有：
    *   优化资源和代码：
        *   图像优化：压缩图片（JPEG，PNG，WebP）、使用响应式图片、设定预加载尺寸，减少文件大小。
        *   代码压缩与合并：压缩和合并CSS、JavaScript文件，减少文件大小和HTTP请求数量。
        *   CSS/JS优化：移除不必要的代码（注释、空格），减少渲染阻塞脚本，将CSS放在顶部，JS放在底部（或使用异步加载）。
        *   减少DOM操作：优化HTML结构，减少DOM元素数量和层级。
    *   优化网络请求和传输：
        *   内容分发网络(CDN)：将内容分发到离用户近的节点，减少延迟。
        *   启用GZIP压缩：在服务器上启用GZIP/Brotli压缩，大幅减少传输数据量。
    *   优化服务器和应用：
        *   减少重定向：避免不必要的301/302跳转。
        *   使用HTTP/2：利用多路复用减少请求开销。

#### 常见FAQ

Q：开发地图应用，加载地图瓦片渲染，需要几十秒才能正常渲染，如何解决？

A：通过Performance抓取Trace进行分析：

跳转Network界面查看请求：

从上面Trace分析，网络请求中存在串行阻塞请求，且请求不通，耗时30s，最终报502异常结束请求。请求阻塞期间，影响页面渲染，导致不能正常显示。将此异常请求修复正常后地图正常加载。

Q：使用预下载提前下载页面资源后，网页加载性能依旧没有提升，为什么？

A：Web组件CacheMode属性不要设置为CacheMode.Online，设置后会强制从网络获取最新资源，不使用任何cache，导致预下载资源不生效。

Q：如何获取Web加载耗时？

A：Web组件的生命周期中onPageBegin事件网页开始加载时触发，onPageEnd事件网页加载完成时触发，计算这两个回调接口耗时，即代表网页加载耗时。