浏览器缓存机制2-应用缓存

浏览器缓存机制2-应用缓存

在公司项目中,一些移动版的WEB页面恰好用到了应用缓存,故顺便写篇文章来总结下应用缓存方面的内容。

1.应用缓存简介

应用缓存(application cache)是HTML5提供的一套缓存机制,使得WEB应用可以离线运行。除了一些旧版本的IE外,现代浏览器如firefox,chrome,safari大部分都是支持HTML5标准的。使用应用缓存主要优势有:

  • 离线浏览:用户可以在离线状态浏览网页内容。
  • 速度更快: 因为数据存储在浏览器缓存中,浏览器只会下载服务器发生改变的资源(只有.appcache文件状态变化时才会重新下载.appcache文件指定的缓存资源),这样可以减轻服务器的负载。

2.应用缓存配置

要开启应用缓存,需要在web页面的html标记中加上manifest属性,如下是我的测试页面test.html代码:

<html manifest="test.appcache">
  <head><title>appcache</title></head>
  <body>test appcache<img src="/test.gif"></img></body>  
</html>

其中test.appcache文件为缓存清单文件(cache manifest),缓存的资源都是在这个清单文件指定。使用了应用缓存后,加载资源的流程是这样的(摘自参考资料1):

  • 1)当浏览器访问一个包含manifest属性的文档时,如果应用缓存不存在,则浏览器加载文档,获取该清单中需要缓存的文件列表,生成应用缓存的第一个版本。

  • 2)后续对该文档以及清单文件中列出的缓存资源的访问会使得浏览器直接从应用缓存加载。同时,浏览器还会向window.applicationCache对象发送一个checking事件,在遵循经典缓存的前提下获取清单文件,关于HTTP经典缓存机制请参见前一篇文章

  • 3)如果当前缓存清单文件是副本是最新的,浏览器将向applicationCache对象发送一个noupdate事件,至此更新过程结束。因此,如果你在服务器上修改了任何缓存资源,需要同时修改清单文件,这样浏览器才知道你的修改

  • 4)如果缓存清单文件已经修改,则清单文件中列出的缓存资源(也包括通过applicationCache.add方法添加到缓存中的文件)会放到一个临时缓存中,对于每个加入到临时缓存的文件,浏览器会向applicationCache发送一个progress事件。如果出现任何错误,浏览器会发送一个error事件,并暂停更新。

  • 5)一旦所以文件都获取成功,它们会被自动移送到真正的离线缓存中,并向applicationCache 对象发送一个 cached 事件。鉴于文档早已经被从缓存加载到浏览器中,所以更新后的文档不会重新渲染,直到页面重新加载(可以手动或通过程序).也就是说,如果你的缓存资源更新了,缓存清单文件也更新了,第一次加载页面的时候并不会更新文档,只有等到页面重新加载的时候才会更新。

为了方便测试,如果需要清除离线缓存,chrome可以通过设置中的清除浏览器数据或者直接访问chrome://appcache-internals/来清除,其他浏览器参照参考资料1.

3.缓存清单文件

一个典型的缓存清单文件test.appcache如下:

CACHE MANIFEST
# v1 - 2015-03-14 23:23
# This is a comment.
CACHE:
test.html
nomanifest.html

NETWORK:
*

FALLBACK:
/fallback fallback.html

缓存清单文件第一行必须是CACHE MANIFEST,然后可以加上注释(以#开头)。此外就是三个段落标题,含义如下:

段落标题 说明
CACHE 显示记录,下面列表是需要切换到应用缓存的显示资源
NETWORK 网络记录,需要从网络访问的白名单列表
FALLBACK 后备记录,请求资源失败时使用

一个应用缓存至少会包含一个资源,由 URI 指定。所有资源除了上面提到的显示记录,网络记录,后备记录外,还有一个类别叫主记录。下面一一来看一下:

1)显示记录

每行都是一个合法的URI与一个要缓存的资源相关联(本段落内不允许通配符)。每行的URI前后允许出现空白字符。显示记录是显示指定的需要加入到应用缓存的资源列表,比如上面示例的test.appcache中需要显示缓存的文件为test.html,nomanifest.html。注意的是,不是所有的文档html属性都要加manifest属性,比如我这个列表里面的nomanifest.html文档就没有manifest属性,但是只要有包含manifest属性的文档被访问后,就会自动加入到应用缓存。

2)网络记录

每一行都是一个合法URI,该段落可以用通配符,比如上面的*,指示了除了应用缓存中之外的资源需要通过网络获取。如果这里不设置的话,那么没有在应用缓存中的资源就无法访问。比如我这里如果不指定NETWORK的话,则test.gif这个图片就无法访问到。

3)后备记录

每一行都是一个合法URI(与一个资源关联),当指定的资源无法访问时访问后面的关联资源。比如访问/fallback或者它的子路径比如/fallback/child路径时,如果没有对应的资源,则会访问fallback.html.

4)主记录

主记录是指html标签中包含了manifest属性的文档,比如下面的main.html。主记录即便没有在显示记录中列出,也会在访问时加入到应用缓存。如main.html作为主记录,虽然没有在CACHE列表中,但是在访问的时候,同样会被加入到应用缓存中。

#main.html
<html manifest="test.appcache">
  <head><title>main</title></head>
  <body>main html</body>
</html>

4.缓存状态(摘自参考资料1)

  • UNCACHED(未缓存):一个特殊的值,用于表明一个应用缓存对象还没有完全初始化。

  • IDLE(空闲):应用缓存此时未处于更新过程中。

  • CHECKING(检查):清单已经获取完毕并检查更新。

  • DOWNLOADING(下载中):下载资源并准备加入到缓存中,这是由于清单变化引起的。

  • UPDATEREADY(更新就绪):一个新版本的应用缓存可以使用。有一个对应的事件 updateready,当下载完毕一个更新,并且还未使用 swapCache() 方法激活更新时,该事件触发,而不会是 cached 事件。

  • OBSOLETE(废弃):应用缓存现在被废弃。
    可以通过下面的代码来测试缓存清单更新情况:

function onUpdateReady() {
  alert('found new version!');
}
window.applicationCache.addEventListener('updateready', onUpdateReady);
if(window.applicationCache.status === window.applicationCache.UPDATEREADY) {
  onUpdateReady();
}

5.总结

  • 显示记录中的资源会被加入应用缓存中。显示记录中的资源文档不一定要在html标签加manifest属性,只要在列表中都会加入应用缓存。
  • 主记录是指html标签包含manifest属性的文档,即便没有在显示记录的列表中,也会加入应用缓存。
  • 应用缓存资源更新后,缓存清单文件也一定要同步更新,不然浏览器没有办法知晓缓存资源的变化。
  • NETWORK段落必须设置,否则其他资源无法访问。
  • 缓存清单文件本身不要在显示记录中,也不要被服务器以任何方式缓存。比如apache可以这样设置缓存清单文件不被缓存。
    ExpiresByType text/cache-manifest "access plus 0 seconds"
  • 如果访问缓存文档时加了参数,比如/test.html?name=test这样,那么也会直接访问应用缓存并加入到应用缓存中。如下面是访问chrome://appcache-internals/得到的记录,可以看到各种类型的记录:
Flags   URL Size (headers and data)
Fallback,   http://localhost/fallback.html  295 B
Master, http://localhost/main.html  703 B
Explicit,   http://localhost/nomanifest.html    305 B
Manifest,   http://localhost/test.appcache  419 B
Explicit,   http://localhost/test.html  732 B
Master, http://localhost/test.html?name=test    732 B

6.参考资料

使用应用缓存(参考了大部分内容并原文摘抄不少内容,向原作者表示感谢)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容