详解HTML5应用程序缓存Application Cache
什么是Application Cache
HTML5引入了应用程序缓存技术,这使得Web应用可以进行缓存,并在没有网络的情况下使用。通过创建cache manifest文件,就能轻松创建离线应用。
Application Cache的优势
- 离线浏览:用户在没有网络连接时仍可访问已缓存的Web应用。
- 提升页面载入速度:由于部分资源已被缓存,再次访问时无需重新下载,从而加快页面加载。
- 降低服务器压力:减少了对服务器资源的请求,降低了服务器的负载。
此外,主流浏览器均已支持Application Cache,即使浏览器不支持,也不会对程序造成影响。
离线存储技术
HTML5提出了两大离线存储技术:localStorage与Application Cache,它们各有不同的应用场景。传统的离线存储技术还有Cookie。
- localStorage:经过实践,
localStorage适合存储一些非关键性的Ajax数据,起到锦上添花的作用。 - Application Cache:主要用于存储静态资源,同样是辅助性的存储方式。
- Cookie:只能保存一小段文本(最大4096字节),因此不能用于存储大数据。由于HTTP是无状态的,服务器为了区分请求是否来自同一客户端,需要一个标识字符串,这个任务由
Cookie完成。每次请求时,这段文本都会在服务器与浏览器之间传递,以验证用户的权限。
由此可见,Application Cache的应用场景与其他缓存技术不同,其使用方式也有所差异。
Application Cache简介
使用Application Cache需要在两个方面进行操作:
- 服务器端:需要维护一个manifest清单。
- 浏览器端:只需进行简单的设置。
以下是一个示例:
<html manifest="demo.appcache">
manifest文件示例
CACHE MANIFEST
# 需要缓存的列表
CACHE:
style1.css
1.jpg
01.js
http://localhost/applicationcache/02.js
http://localhost/applicationcache/zepto.js
# 不需要缓存的
NETWORK:
4.jpg
# 访问缓存失败后,备用访问的资源,第一个是访问源,第二个是替换文件*.html /offline.html
FALLBACK:
2.jpg/3.jpg
错误处理
在使用过程中,可能会遇到如下错误:
Application Cache Error event: Manifest fetch failed (404)
该错误的原因是manifest文件需要配置正确的MIME - type,即 “text/cache - manifest”,且必须在Web服务器上进行配置,不同的服务器配置方式不同。
离线应用示例
\APPLICATIONCACHE
01.js
02.js
1.jpg
2.jpg
3.jpg
4.jpg
demo.appcache
index.html
style1.css
style2.css
web.config
zepto.js
配置好上述内容后,就可以实现离线应用。此时,即使断网,这些文件依然可以访问。
需要注意的是,如果manifest文件中不包含/index.html,浏览器会将 “applicationcache/” 进行缓存,实际上这就相当于缓存了index.html。
manifest文件的结构
manifest文件可分为三个部分:
- CACHE MANIFEST:在此标题下列出的文件将在首次下载后进行缓存。
- NETWORK:在此标题下列出的文件需要与服务器保持连接,不会被缓存。
- FALLBACK:在此标题下列出的文件规定了当页面无法访问时的回退页面(例如404页面)。
事件处理
HTML5定义了几个事件点,但在大多数情况下,我们无需主动使用JavaScript进行操作,完全可以依赖浏览器的默认处理机制。
尺寸限制
Application Cache的尺寸限制统一为5M。以下是一个测试示例:
Document was loaded from Application Cache with manifest http://localhost/applicationcache/demo.appcache
index.html:1 Application Cache Checking event
index.html:6 GET http://localhost/applicationcache/style2.css net::ERR_FAILED
index.html:1 Application Cache NoUpdate event
index.html:11 GET http://localhost/applicationcache/2.jpg net::ERR_FAILED
index.html:12 GET http://localhost/applicationcache/3.jpg net::ERR_FAILED
从上述示例可以看出,当两个CSS文件的大小超过5M时,style2.css就无法被缓存。这可能会导致一些问题,例如,如果A频道和B频道都维护了自己的Application Cache,当A频道的缓存使用达到峰值时,可能会导致B频道的所有缓存失效。因此,建议Application Cache用于存储公共资源,而不要存储业务资源。
一些问题
更新机制问题
首次更新manifest文件时,由于页面加载已经开始甚至完成,而缓存更新尚未完成,浏览器仍然会使用过期的资源。当Application Cache有更新时,浏览器在本次访问中不会使用新资源,而是在第二次访问时才会使用。可以在update事件中执行window.reload事件来解决这个问题:
window.applicationCache.addEventListener("updateready", function(){
window.location.reload();
});
缓存更新问题
缓存不仅仅会存储显式定义的文件,例如在上述示例中,缓存 “applicationcache/” 时会默认保存index.html作为映射数据,并且会包含demo.appcache文件。很多时候,线上文件更新后,缓存却没有更新,此时只需在manifest配置文件中进行一点修改即可触发更新。
例如,将代码从:
<html manifest="demo.appcache">
修改为:
<html manifest="demo1.appcache">
如果不更新demo.appcache,缓存将不会更新,因为index.html被缓存了,浏览器检测的仍然是原manifest清单。
页面管理问题
各个页面如果统一管理自己的manifest清单,例如a页面和b页面都配置了common.js,当a页面更新后,如果b页面的manifest不更改,b页面依旧会读取老版本的文件。这种方式有一定的合理性,但也存在资源浪费的问题,需要对公共页面进行特殊处理。
总结
从可用性和易用性来看,Application Cache是值得使用的,但它更适合用于静态资源的缓存。要真正实现离线应用,还需要付出更多的努力。