Android Webview H5 加载速度优化方案

时间:2024-05-22 16:31:03

一、背景


由于H5具备 开发周期短、灵活性好 的特点,所以现在 App大多嵌入了 Webview 组件进行 Hybrid 开发,但 APP Webview 存在令人烦恼的性能问题,特别突出的是:加载速度慢 & 消耗流量。

Android Webview H5 加载速度优化方案


1.1、渲染速度慢

前端 H5 页面渲染的速度取决于两个方面:Js 解析效率、手机硬件设备的性能。

  • Js 解析效率:Js 本身的解析过程复杂、解析速度不快 & 前端页面涉及较多 JS 代码文件,所以叠加起来会导致 Js 解析效率非常低。
  • 手机硬件设备的性能:由于Android机型碎片化,这导致手机硬件设备的性能不可控,而大多数的Android手机硬件设备无法达到很好很好的硬件性能

 

1.2、页面资源加载缓慢

H5页面一般会比较多,每加载一个 H5页面,都会产生较多网络请求:

  • HTML 主 URL 自身的请求;
  • HTML外部引用的JS、CSS、字体文件,图片也是一个独立的 HTTP 请求

每一个请求都串行的,这么多请求串起来,这导致 H5页面资源加载缓慢。

总结:上述问题导致了 APP 内嵌的 H5 页面用户体验与原生 Native 界面存在较大差距。


二、优化方案


2.1、图片资源按需加载

实现复杂度:★☆☆☆☆,效果预计:★★★★★

图片资源占我们H5界面(尤其是商品详情页)中绝大多数流量,可以在 user-agent 中加入客户端屏幕分辨率,前端H5根据分辨率来决定展示多大的缩略图。如果是商品详情页的话可以采用和手淘类似的交互方案:默认显示缩略图,点击显示原图以便用户下载图片。

实现方式:客户端加载H5界面时在 user-agent 中加入屏幕分辨率。


2.2、加 CDN

实现复杂度:★☆☆☆☆,效果预计:★★☆☆☆,需要收费

CDN 的全称是Content Delivery Network,即内容分发网络,它具有以下优势:减少带宽需求量,提供服务器端加速,解决由于用户访问量大造成的服务器过载问题,服务商能使用Web Cache技术在本地缓存用户访问过的Web页面和对象。

实现方式:这个方案只需要运维在阿里云进行配置即可,需要费用。


2.3、浏览器缓存机制

实现复杂度:★☆☆☆☆,效果预计:★★★☆☆

根据 HTTP 协议头里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段来控制文件缓存的机制。

常见用法是:Cache-Control与 Last-Modified 一起使用;Expires与 Etag一起使用;即一个用于控制缓存有效时间,一个用于在缓存失效后,向服务查询是否有更新。特别注意:浏览器缓存机制 是 浏览器内核的机制,一般都是标准的实现,即Cache-Control、 Last-Modified 、 Expires、 Etag都是标准实现,你不需要操心。

不足:缓存文件需要首次加载后才会产生;浏览器缓存的存储空间有限,缓存有被清除的可能;缓存的文件没有校验。

应用场景:静态资源文件的存储,如JS、CSS、字体、图片等。

缓存存储路径:Android Webview 会将缓存的文件记录及文件内容会存在当前 app 的 data 目录中。

实现方式:前端人员在 H5 界面的 HTTP 协议头里添加缓存机制,客户端人员在本地放开缓存限制,跟着 H5 的缓存机制走。


2.4、离线包

实现复杂度:★★★★☆,效果预计:★★★☆☆

为了有效解决 Android WebView 的性能问题,除了使用 Android WebView 自身的缓存机制,还可以自己针对某一需求场景构建缓存机制。

Android Webview H5 加载速度优化方案

实现方式:

  1. 事先将更新频率较低、常用 & 固定的H5静态资源 文件(如JS、CSS文件、图片等) 放到本地,并做好资源版本控制,每次打开APP时调用服务端接口询问是否更新资源文件,是的话进行覆盖。
  2. 拦截H5页面的资源网络请求 并进行检测。
  3. 如果检测到本地具有相同的静态资源 就 直接从本地读取进行替换 而 不发送该资源的网络请求 到 服务器获取。


2.5、客户端优化

实现复杂度:★★☆☆☆,效果预计:★☆☆☆☆

客户端本地优化,如Android Webview 预创建。

Android 实现方式:本地Webview初始化都要不少时间,首次初始化webview与第二次初始化不同,首次会比第二次慢很多。原因预计是webview首次初始化后,即使 webview 已经释放,但一些webview 共用的全局服务或资源对象仍没有释放,第二次初始化时不需要再生成这些对象从而变快。我们可以在Application预先初始化好WebView, 当第二次初始化WebView的时候速度就快多了, 或者直接将其拿来使用。