Android WebVIew缓存机制详解

前言

由于H5具备 开发周期短、灵活性好 的特点,所以现在Android App大多嵌入了Android Webview组件进行Hybrid开发

但我知道你一定在烦恼Android Webview的性能问题,特别突出的是:加载速度慢 & 消耗流量

今天,我将针对Android Webview的性能问题,提出一些有效解决方案。

目录

1.WebView的性能问题

1.1 H5页面加载速度慢

1.1.1 渲染速度慢

1.1.2 页面资源加载缓慢

1.2 耗费流量

2. WebView网页缓存

2.1 浏览器缓存机制

2.2 Application Cache缓存机制

2.3 Dom Storage缓存机制

2.4 Database缓存机制

2.5 IndexedDB缓存机制 

2.6 File System

2.7 缓存机制汇总

3 缓存模式


1.WebView的性能问题

1.1 H5页面加载速度慢

1.1.1 渲染速度慢

前端H5页面渲染的速度取决于 两个方面:

Js解析效率

Js本身的解析过程复杂、解析速度不快 & 前端页面涉及较多JS代码文件,所以叠加起来会导致Js解析效率非常低

手机硬件设备的性能

由于Android机型碎片化,这导致手机硬件设备的性能不可控,而大多数的Android手机硬件设备无法达到很好很好的硬件性能

总结:上述两个原因 导致 H5页面的渲染速度慢。

1.1.2 页面资源加载缓慢

H5页面一般会比较多,每加载一个H5页面,都会产生较多网络请求,HTML主URL自身的请求,HTML外部引用的JS、CSS、字体文件,图片也是一个独立的HTTP请求。

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

1.2 耗费流量

每次使用H5页面时,用户都需要重新加载Android WebView的H5页面,每加载一个H5页面,都会产生较多网络请求(上面提到),每一个请求都串行的,这么多请求串起来,这导致消耗的流量也会越多。

上述问题导致了Android WebView的H5页面体验 与 原生Native存在较大差距。

2. WebView网页缓存

缓存,即离线存储,这意味着H5网页 加载后会存储在缓存区域,在无网络连接时也可访问

WebView的本质 = 在Android中嵌入H5页面,所以,Android WebView自带的缓存机制其实就是H5页面的缓存机制

Android WebView除了新的File System缓存机制(H5页面新加入的缓存机制,后面会进行简单介绍)还不支持,其他都支持。

Android WebView自带的缓存机制有5种:

  1. 浏览器 缓存机制
  2. Application Cache缓存机制
  3. Dom Storage缓存机制
  4. Web SQL Database缓存机制
  5. Indexed Database缓存机制

2.1 浏览器缓存机制

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

下面详细介绍Cache-Control、Expires、Last-Modified&Etag四个字段

Cache-Control:用于控制文件在本地缓存有效时长

如服务器回包:Cache-Control:max-age=600,则表示文件在本地应该缓存,且有效时长是600秒(从发出请求算起)。在接下来600秒内,如果有请求这个资源,浏览器不会发出 HTTP 请求,而是直接使用本地缓存的文件。

Expires:与Cache-Control功能相同,即控制缓存的有效时间

Expires是HTTP1.0标准中的字段,Cache-Control 是HTTP1.1标准中新加的字段

当这两个字段同时出现时,Cache-Control优先级较高

Last-Modified:标识文件在服务器上的最新更新时间

下次请求时,如果文件缓存过期,浏览器通过 If-Modified-Since 字段带上这个时间,发送给服务器,由服务器比较时间戳来判断文件是否有修改。如果没有修改,服务器返回304告诉浏览器继续使用缓存;如果有修改,则返回200,同时返回最新的文件。

Etag:功能同Last-Modified,即标识文件在服务器上的最新更新时间。

不同的是,Etag的取值是一个对文件进行标识的特征字串。

在向服务器查询文件是否有更新时,浏览器通过If-None-Match字段把特征字串发送给服务器,由服务器和文件最新特征字串进行匹配,来判断文件是否有更新:没有更新回包304,有更新回包200

Etag和Last-Modified可根据需求使用一个或两个同时使用。两个同时使用时,只要满足基中一个条件,就认为文件没有更新。

常见用法是:

Cache-Control与Last-Modified一起使用;

Expires与Etag一起使用;

即一个用于控制缓存有效时间,一个用于在缓存失效后,向服务查询是否有更新

特点

优点:支持Http协议层

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

对于解决以上问题,可以参考手 Q 的离线包

应用场景

静态资源文件的存储,如` JS、CSS`、字体、图片等。

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

具体实现

浏览器缓存机制是浏览器内核的机制,一般都是标准的实现,即Android WebView内置自动实现。

2.2 Application Cache缓存机制

以文件为单位进行缓存,且文件有一定更新机制(类似于浏览器缓存机制)

AppCache原理有两个关键点:manifest 属性和 manifest 文件。

HTML 在头中通过 manifest 属性引用 manifest 文件

manifest 文件:就是上面以 appcache 结尾的文件,是一个普通文件文件,列出了需要缓存的文件

浏览器在首次加载 HTML 文件时,会解析 manifest 属性,并读取 manifest 文件,获取 Section:CACHE MANIFEST 下要缓存的文件列表,再对文件缓存

// 原理说明如下:

AppCache 在首次加载生成后,也有更新机制。被缓存的文件如果要更新,需要更新 manifest 文件

因为浏览器在下次加载时,除了会默认使用缓存外,还会在后台检查 manifest 文件有没有修改(byte by byte)

发现有修改,就会重新获取 manifest 文件,对 Section:CACHE MANIFEST 下文件列表检查更新

manifest 文件与缓存文件的检查更新也遵守浏览器缓存机制

如用户手动清了 AppCache 缓存,下次加载时,浏览器会重新生成缓存,也可算是一种缓存的更新

AppCache 的缓存文件,与浏览器的缓存文件分开存储的,因为 AppCache 在本地有 5MB(分 HOST)的空间限制

特点

方便构建Web App的缓存,专门为Web App离线使用而开发的缓存机制,AppCache 是对浏览器缓存机制的补充。

应用场景

存储静态文件(如JS、CSS、字体文件)

具体实现     

   // 通过设置WebView的settings来实现
        WebSettings settings = getSettings();
        String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
        settings.setAppCachePath(cacheDirPath);
        // 1. 设置缓存路径
        settings.setAppCacheMaxSize(20*1024*1024);
        // 2. 设置缓存大小
        settings.setAppCacheEnabled(true);
        // 3. 开启Application Cache存储机制

注意,每个 Application 只调用一次 WebSettings.setAppCachePath() 和WebSettings.setAppCacheMaxSize()

2.3 Dom Storage缓存机制

通过存储字符串的Key - Value对来提供

DOM Storage分为sessionStorage&localStorage; 二者使用方法基本相同,区别在于作用范围不同:

a.sessionStorage:具备临时性,即存储与页面相关的数据,它在页面关闭后无法使用

b.localStorage:具备持久性,即保存的数据在页面关闭后也可以使用。

特点

存储空间大( 5MB):存储空间对于不同浏览器不同,如Cookies 才 4KB

存储安全、便捷:Dom Storage存储的数据在本地,不需要经常和服务器进行交互

不像Cookies每次请求一次页面,都会向服务器发送网络请求

应用场景

存储临时、简单的数据

代替 将 不需要让服务器知道的信息 存储到cookies的这种传统方法

Dom Storage机制类似于Android的SharedPreference机制

具体实现     

// 通过设置 `WebView`的`Settings`类实现
WebSettings settings = getSettings();
// 开启DOM storage
settings.setDomStorageEnabled(true);
        

2.4 Database缓存机制

基于 `SQL` 的数据库存储机制

特点

充分利用数据库的优势,可方便对数据进行增加、删除、修改、查询

应用场景

存储适合数据库的结构化数据

具体实现      

  // 通过设置WebView的settings实现
        WebSettings settings = getSettings();
        String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
        settings.setDatabasePath(cacheDirPath);
        // 设置缓存路径
        settings.setDatabaseEnabled(true);
        // 开启 数据库存储机制

根据官方说明,Web SQL Database存储机制不再推荐使用(不再维护),取而代之的是IndexedDB缓存机制。

2.5 IndexedDB缓存机制 

属于NoSQL数据库,通过存储字符串的Key - Value对来提供

类似于Dom Storage 存储机制的key-value存储方式

特点

功能强大、使用简单,通过数据库的事务机制进行数据操作,可对对象任何熟悉生成索引,方便查询。

存储空间大,默认250MB,比Dom Storage大很多。

使用灵活,以Key-Value的方式存取对象,可以使任何类型值或对象,包括二进制。

异步的API调用,避免造成等待而影响体验。

应用场景

存储 复杂、数据量大的结构化数据

具体实现

// 通过设置WebView的settings实现 ,只需设置支持JS就自动打开IndexedDB存储机制,Android 在4.4开始加入对 IndexedDB 的支持,只需打开允许 JS 执行的开关就好了。

  WebSettings settings = getSettings();
  settings.setJavaScriptEnabled(true);

 

2.6 File System

为H5页面的数据 提供一个虚拟的文件系统

可进行文件(夹)的创建、读、写、删除、遍历等操作,就像Native App访问本地文件系统一样

虚拟的文件系统是运行在沙盒中

不同WebApp的虚拟文件系统是互相隔离的,虚拟文件系统与本地文件系统也是互相隔离的。

虚拟文件系统提供了两种类型的存储空间:临时 & 持久性:

临时的存储空间:由浏览器自动分配,但可能被浏览器回收

持久性的存储空间:需要显式申请;自己管理(浏览器不会回收,也不会清除内容);存储空间大小通过配额管理,首次申请时会一个初始的配额,配额用完需要再次申请。

特点

可存储数据体积较大的二进制数据,可预加载资源文件,可直接编辑文件。

应用场景

通过文件系统 管理数据

具体使用

由于File System是H5新加入的缓存机制,所以Android WebView暂时不支持

2.7 缓存机制汇总

3 缓存模式

缓存模式是一种 当加载H5网页时 该如何读取之前保存到本地缓存

从而进行使用 的方式

即告诉Android WebView什么时候去读缓存,以哪种方式去读缓存

Android WebView自带的缓存模式有4种:

// 缓存模式说明:

      // LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据

      // LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.

      // LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。

      // LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

具体使用

WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章