H5笔记3-资源缓存

问题描述:

在开发h5的webapp时,会需要考虑app的页面加载性能流量节省离线缓存等问题。解决这类问题的一种方法可以考虑appcache技术,它可以将一些静态资源缓存到客户端本地,这样同一个资源不用反复的从服务器请求并下载到本地了,既可以提高页面的加载性能,也能节省一些流量。

如何使用appcache技术?

appcache缓存技术主要通过配置文件实现。自定义一个appcache结尾的配置文件,配置需要缓存的资源,然后将这个配置文件引入到需要使用缓存的前台页面就行了。

1.自定义配置文件

定义一个配置文件,文件名称自己随便命名,但是结尾格式为appcache。
这个就是缓存配置文件。文件配置信息如下:

CACHE MANIFEST
#v2.0.0(更新客户端缓存文件的话,修改版本号就行了)

#需要缓存的文件列表;系统级别的,不经常变的文件可以放在这里;
CACHE:
../../../static/bootstrap/css/bootstrap.min.css
../../../static/bootstrap/css/bootstrap-theme.min.css
../../../static/jquery/jquery.min.js
../../../static/css/model.css
../../../static/css/style.css
../../../static/HBuilder/css/mui.min.css
../../../static/HBuilder/js/mui.min.js
../../../static/js/comm.js
../../../static/android/android-require-min-v2.1.11.js
../../../static/android/android-v0.0.1.js
../../../static/js/ajaxSetup.js
../../../static/img/index_bg.png
../../../static/HBuilder/fonts/mui.ttf


#不需要缓存的文件列表;与模块相关的动态脚本文件等放在这里;
NETWORK:  
*

#代替方案;找不到的资源可以用其他的资源代替
FALLBACK:

注意:
文件第一行必须是CACHE MANIFEST关键字,些其他的信息的话,缓存会不好用;
相对路径是相对这个缓存配置文件而言的,并不是相对前台页面;

2.引用配置文件

将配置文件通过manifest属性引入到前台页面的html元素里:

<!DOCTYPE html>
<html manifest="../zsfy/login/cache/beforeLogin.appcache">
  <head>
    <meta charset="utf-8" />
    <title>登录引导页</title>

浏览器访问这个页面,用f12查看调试页面的resources选项,缓存信息如下:
这里写图片描述

缓存成功的话,控制台信息如下:
这里写图片描述

可以看到总共缓存了14个文件。

当再次访问这个页面时,浏览器就会直接从缓存里拿资源文件了:
这里写图片描述

这里写图片描述

缓存加载过程如图:
这里写图片描述

注意:
(1) manifest的加载是晚于页面其他资源的。浏览器先加载引用的资源(从服务器或缓存中拿),再通过检查 manifest 文件是否有更新来更新缓存文件。这样缓存文件可能用的不是最新的版本。这个是比较坑的。。。

(2)不同的html页面,配置不同的manifest文件,他们的缓存空间是单独分开的,缓存的资源之间相互独立。验证这个结论的方法:
★ 定义一个manifest文件,配置缓存资源test.js文件;
★ a.html页面和b.html页面配置manifest文件;
★ 浏览器访问a.html页面,用F12查看test.js里面的内容;
★ 更改服务器里的test.js文件内容,浏览器访问b.html页面,用F12查看test.js里面的内容为更改后的内容;
★ 浏览器访问a.html页面,用F12查看test.js里面的内容;反复刷新页面,发现还是更改之前的内容;
可见,不同页面的缓存空间是独立的。但是整个网站的缓存上限通常是5M.

(3)不同的html页面,配置同一个manifest文件,他们的缓存空间是共享的。比如a,b两个页面引用同一份manifest A. 则更新A,更新R,刷新b, b对应的R资源更新后,a的R资源副本也会随之更新. 这就是cache group的机制。a和b对应的application cache,同属于同一个application cache group

(4)如果manifest文件或者是其中指定的某个资源下载失败的话,整个cache的更新都会失败。在这种情况下,浏览器将会使用老的application cache。

如何更新缓存?

有缓存必然涉及到缓存的更新,更新缓存的方法如下:

(1)更改manifest文件
每当manifest文件有更改,哪怕是加了一个空格,浏览器会重新下载资源文件进行缓存。通常做法是通过修改注释信息里的版本号来实现文件的更改。

(2)手动清除浏览器历史记录
如用用户手动清了浏览器缓存,下次加载时,浏览器会重新生成缓存,也可算是一种缓存的更新。

(3)js脚本更新缓存
在程序中,你可以通过window.applicationCache 对象来访问浏览器的app cache。你可以查看 status 属性来获取cache的当前状态:

var appCache = window.applicationCache;

switch (appCache.status) {

  case appCache.UNCACHED: // UNCACHED == 0

    return ‘UNCACHED’;

    break;

  case appCache.IDLE: // IDLE == 1

    return ‘IDLE’;

    break;

  case appCache.CHECKING: // CHECKING == 2

    return ‘CHECKING’;

    break;

  case appCache.DOWNLOADING: // DOWNLOADING == 3

    return ‘DOWNLOADING’;

    break;

  case appCache.UPDATEREADY:  // UPDATEREADY == 4

    return ‘UPDATEREADY’;

    break;

  case appCache.OBSOLETE: // OBSOLETE == 5

    return ‘OBSOLETE’;

    break;

  default:

    return ‘UKNOWN CACHE STATUS’;

    break;

};

为了通过编程更新cache,首先调用 applicationCache.update()。这将会试图更新用户的 cache(要求manifest文件已经改变)。最后,当 applicationCache.status 处于 UPDATEREADY 状态时, 调用applicationCache.swapCache(),旧的cache就会被置换成新的。

var appCache = window.applicationCache;

appCache.update(); // Attempt to update the user’s cache.

…

if (appCache.status == window.applicationCache.UPDATEREADY) {

  appCache.swapCache();  // The fetch was successful, swap in the new cache.

}

像这样使用 update()和swapCache()并不会将更新后的资源 呈现给用户。这仅仅是让浏览器检查manifest文件是否发生了更新,然后下载指定的更新内容,重新填充app cache。因此,要让用户看到更新后的内容,需要两次页面下载,一次是更新app cache,一次是更新页面内容。

好消息是,你可以避免两次页面下载带来的麻烦。为了让用户能看到你的站点的最新版本,设置一个监听器来监听页面加载时的updateready 事件。

// Check if a new cache is available on page load.

window.addEventListener(‘load’, function(e) {

  window.applicationCache.addEventListener(‘updateready’, function(e) {

    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {

      // Browser downloaded a new app cache.

      // Swap it in and reload the page to get the new hotness.

      window.applicationCache.swapCache();

      if (confirm(‘A new version of this site is available. Load it?’)) {

        window.location.reload();//重点在这里!!!!

      }

    } else {

      // Manifest didn’t changed. Nothing new to server.

    }

  }, false);

}, false);

appcache知识点总结

(1)备用资源FALLBACK列表里的资源,必须与当前的manifest同源;备用资源也会被缓存.
(2)备用名称空间 和 白名单名称空间 都可以使用前缀匹配模式。即支持通配符匹配模式。可以放心的是 //www.a.com/abc 是不匹配 //www.a.com/ab的,因为//www.a.com/ab 实际上是//www.a.com/ab/
(3)前缀匹配对端口的匹配是宽松的.如abc.com:80/a.png 就会被 abc.com/所匹配.
(4)window. applicationCache.update(), 只会立刻检测manifest文件,而不会更新相应资源;
(5)一组不同的页面引入同一个manifest文件时,这组页面构成一个group.并已document作为标识,来区分他们。其中任何一个的manifest或资源更新,甚至是检测都会触发其他页面的applicationCache的相应事件.
(6)a,b两个页面引入相同资源,但a有使用manifest而b没有。那么即使a页面缓存了资源,这个缓存对b页面也不会有效。
(7)为manifest文件配置304相关头域时,也配置expires和cache-control : max-age。因为chrome,safari,以及android,如果没有expires 或 max-age时,是不会有304的,而只会是200。opera则无视一切http cache头域.总是200。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值