manifest离线缓存机制

总结下:

1:页面的首次加载,获取manifest在内的所有文件,根据manifest文件的内容,该缓存的缓存;

2,第二次加载,先从缓存中取出manifest文件,里面列出的缓存文件,直接从缓存读取,然后去请求网络的manifest和其他文件,若新的mannifest文件版本和旧的一样,则没有变动。若有变动则取出需要缓存的文件放入本地,根新本地文件。

3,但是,已经被渲染的页面不会重新刷新,即即使服务端根新manifest文件后,客户端的第一次刷新还是上一次的文件,第二次刷新才是更新后的文件,这是离线缓存的机制导致的问题,会有体验上的不足。
4,解决方案:用代码进行手动缓存的刷新解决,调用cache.update()进行缓存刷新,cache.swapCache()进行重新请求更新的资源进行渲染。

一、基本概念
离线缓存是HTML5新引入的技术,能够让你的Web应用程序指定哪些文件可以缓存在本地,使得你的网络断开时依然可以通过本地的缓存来进行访问浏览。

二、使用方法

  1. MIME type 声明

首先,因为manifest文件必须是一个MIME type为text/cache-manifest类型的存在。文件后缀名可以自定义(建议为.appcache)所以我们需要现在服务端将.appcache后缀的文件类型声明为text/cache-manifest。以apache为例,我们需要在httpd.conf中加上:

AddType text/cache-manifest .appcache

  1. 在HTML文件中引入manifest文件

<!DOCTYPE html>

其中manifest文件的后缀名必须为.appcache,并且和引入该manifest的页面同源

  1. manifest文件语法
CACHE MANIFEST
# 上面这行是必须的

# 这是一行注释
# 在这个文件中的任何地方都可以添加
# 它们全部都会被忽略
  # 在注释之前可以有空格
  # 但必须是在单行前

# 空行也会被忽略

# 这些列在最开始的文件都是需要被缓存的
# 或者是那些列在"CACHE:"里的, "CACHE"头必须写在这些文件之前,如同
# 下面写好的那样
images/sound-icon.png
images/background.png
# 注意,每个文件必须单独一行

# 在线白名单中出现的这个文件,它不会被缓存,并且,
# 对该文件的引用,将绕过缓存,总是会
# 从网络中获取目标(或在用户离线时,尝试从网路上获取)
NETWORK:
comm.cgi

# 这是另一块要缓存的文件,这次只有一个css文件
CACHE:
style/default.css

我们也可以书写成这样:


CACHE MANIFEST
#version 1.0
CACHE:
style/default.css
images/sound-icon.png
images/background.png
NETWORK:
*

CACHE MANIFEST:这个是必须的,并且一定要写在manifest文件开头
CACHE:缓存清单列表,此处列出的为需要进行离线缓存的资源文件
NETWORK: 白名单列表,需要与服务端进行交互获取的资源文件,此处必须列出除缓存清单列表以外所有的资源地址(可以使用通配符*星号代替),否则没有列出的资源文件将加载失败
引入manifest的页面,即使没有被列入缓存清单中,仍然会被用户代理缓存。并且无法通过白名单列表去除。

(缓存清单的文件列表可以使用绝对路径或绝对URL地址)

开启离线缓存后,我们可以在chrome中打开f12来看看资源加载有啥区别

可以看出,使用离线缓存后的资源,资源请求的状态码都变为200,并且在size栏中都被标明为(form cache),加载速度也是显而易见的。

  1. 缓存如何更新?

资源被离线缓存后,无论我们在后端如何更改资源文件,客户端都不会拉取到修改过的文件。

原来,只有当manifest文件被更新后(修改文件任何地方,包括注释等),客户端才会更新离线缓存文件,并且每次都会更新全部的缓存文件,包括没有被修改的资源文件,但一般这些文件都会走304的缓存策略。

另外,在服务端修改manifest文件后,客户端第一次访问页面需要再刷新一次才能获取最新的资源。因为对于浏览器来说,manifest的加载是要晚于其他资源的. 这就导致check manifest的过程是滞后的。发现manifest改变,所有浏览器的实现都是紧随这做静默更新资源,以保证下次pv,应用到更新。(这一点很蛋疼,但还是有解决办法,请继续往下看)。

  1. 离线缓存对象和事件处理

在javascript中我们可以通过window.applicationCache来访问缓存对象,对象中包含了一个status属性以及若干的待监听的事件处理器。

其中status属性代表的是当前离线应用的状态,它可能的值为:

UNCACHED (0):未启用离线应用
IDLE (1):已开启离线应用,但本地缓存的资源是最新的,并且未标记为废弃资源
CHECKING (2):当前更新缓存的状态为“检查中”
DOWNLOADING (3):当前更新缓存的状态为“下载资源中”
UPDATEREADY (4):当前更新缓存的状态为“更新完毕”
OBSOLETE (5):已开启离线应用,但缓存资源都已标记为废弃
离线缓存事件:

checking:在第一次下载manifest文件时,或者检查是否需要更新时触发
noupdate:manifest文件未修改,不需要下载新的缓存文件时触发
downloading:准备更新缓存之前,或者第一次下载资源之前触发
progress:下载资源时触发,每下载一个资源都会触发一次
cached:页面首次启用离线缓存,并且离线缓存下载完毕时触发
updateready:资源更新完毕时触发
obsolete:加载manifest文件时遇到401或404错误时触发
errorEvent加载manifest文件时遇到401或404错误时触发
这样,我们就可以通过updateready事件来让离线缓存更新后自动刷新页面了,虽然还是比较挫:

applicationCache.addEventListener(‘updateready’, function(){
location.href=”test.html”;
}, false);

  1. 离线缓存的下线

要将离线缓存下线,我们只需要将服务端的manifest文件删除即可,同时也要将HTML中的 manifest="manifest.appcache" 删除(不删也可以,会在console控制台报错,但不会影响页面访问),删除后用户再第一次访问还是原来的缓存页面,还需要再刷新一次.

webview的缓存现象

通常, webview的缓存有如下三种现象:

普通网页(无manifest文件), 不受manifest缓存影响, 缓存只走 http cache.
包含manifest文件的网页, 缓存文件只受manifest缓存影响(只有manifest文件改变时才会更新缓存资源), 缓存资源完全与 http cache 无关, 但是 NETWORK 段落后需要访问网络的文件, 将继续走 http cache.
webview直接加载manifest缓存过的文件时, 优先加载第一个manifest缓存的该文件, 如果没有找到manifest缓存, 那么它将自动寻找 http cache 或者 在线加载.

最佳实践

通常只使用一个manifest文件, 并保证缓存的文件尽可能的少, 以减小manifest每次更新清单中文件所耗费的时间和流量.
如果一定要使用两个及以上manifest文件, 缓存文件请尽量不要相同.
如果以上两条都不能保证, 那么, 请保证尽可能在manifest缓存的状态更新时, 主动去刷新网页.(此时并不能保证不同网页之间同一个缓存文件版本一致)

具体落地步骤

如果缓存的文件需要加参数运行, 建议将参数内容加到hash中, 如:cached-page.html#parameterName=value

manifest 的引入可以使用绝对路径或者相对路径, 如果你使用的是绝对路径, 那么你的manifest文件必须和你的站点处于同一个域名下.

manifest文件你可以保存为任意的扩展名, 但是响应头中以下字段须取以下定值, 以保证manifest文件正确被解析, 并且它没有http缓存.

Content-Type: text/cache-manifest
Cache-Control: max-age=0
Expires: [CURRENT TIME]
### 如何更新缓存

更新manifest文件后, webview将自动更新缓存.
js更新缓存(手动触发manifest更新): window.applicationCache.update();

转载于:https://www.cnblogs.com/jeremy123/p/7372198.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值