随着移动互联网越来越普及, 在移动端采用web技术解决跨平台、快速部署、快速发布的方案也越来越多。 但对于web方式实现的app又面临者网络的强依赖,对网速和流量有较高要求,针对此问题html提出了AppCache方案, 用于解决web离线缓存问题。
那什么是AppCache呢?
顾名思义,AppCache就是对app内存缓存的方案,具体表现为当请求某个文件时不是从网络获取该文件,而是从本地获取。
AppCache好处
应用程序缓存为应用带来三个优势:
- 离线浏览 - 用户可在应用离线时使用它们
- 速度 - 已缓存资源加载得更快
- 减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源
下面我们来看个例子:
未添加AppCache情况
文件夹下有4个文件,

文件内容如下: index.html
<!DOCTYPE HTML>
<html>
<head>
<title>AppCache</title>
<script src="index.js"></script>
<link rel="stylesheet" href="index.css" target="_blank" rel="external nofollow" >
</head>
<body>
<img src="logo.jpg">
<p>The time is: <output id="current_date"></output></p>
</body>
</html>
index.css
output { font: 2em sans-serif; }
index.js
setInterval(function () {
document.getElementById('<span style="font-family: Arial, Helvetica, sans-serif;">current_date</span><span style="font-family: Arial, Helvetica, sans-serif;">').value = new Date();</span>
}, 1000);
请求index.html, 会依次下载以下文件:
1 http://localhost/demo/wqjsdk/test_apps/AppCache/index.html
2 http://localhost/demo/wqjsdk/test_apps/AppCache/index.css
3 http://localhost/demo/wqjsdk/test_apps/AppCache/index.js
4 http://localhost/demo/wqjsdk/test_apps/AppCache/logo.jpg
再次刷新页面也会更新这些文件(当文件内容并无实际更新是也会发起http请求, http返回304, 但也会发起http请求)
观察htto request header可以看到pragma设置了no-cache
Cache-Control max-age=0
Pragma no-cache
添加AppCache
添加文件index.appcache, 内容为:
CACHE MANIFEST
index.html
index.css
index.js
logo.jpg
同时修改index.html, 添加
<html manifest="index.appcache">
再次请求index.html,
结果如下,第一次请求会把所有文件都拉下来,这里就不列出了, 同时会请求index.appcache文件.
刷新页面会发现只请求了一个文件:
1 http://localhost/demo/wqjsdk/test_apps/AppCache/index.appcache
这时修改index.html文件再次请求并不会更新index.html文件, 说明index.html已经缓存,并不会从server端获取。
更新缓存
一旦应用被缓存,它就会保持缓存直到发生下列情况:
- 用户清空浏览器缓存
- manifest 文件被修改
- 由程序来更新应用缓存
更新appcache文件会导致所有文件重新请求,
注: 更新index.appcache会导致所有文件都重新请求, 但当次并不生效而是要等到下一次请求才能生效, 当次显示还是采用之前缓存过得文件。
appcache文件格式
manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。
manifest 文件可分为三个部分:
- CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存,等价于CACHE:
- NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
- FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)
我们更新index.appcache文件如下
CACHE MANIFEST
index.css
CACHE:
logo.jpg
NETWORK:
*
FALLBACK:
info.html 404.html
注意: 主页一定会被缓存起来的,因为AppCache主要是用来做离线应用的,如果主页不缓存就无法离线插件了,因此把index.html添加到NETWORK中是不起效果的。
详细可以查看http://www.whatwg.org/specs/web-apps/current-work/#offline
AppCache不足
AppCache设计初衷是为了离线查看,尽量把能离线的文件缓存到本地,以供离线时能正常查看 ,但对在线更新并未提供太多机制和优化方案。html5 AppCache虽然没有提供太多定制, 但我们可以根据不同应用场景提供不同的优化方案:
比如针对hybrid方案,可改进点: 1、 对manifest文件更新,会重新请求所有文件,实际上可能只更新了很少量文件。( 虽然重新请求资源会返回304, 但每个文件还会发起请求) 针对此点可以只更新需要更新的文件, 比如可以建立一个文件版本或者MD5映射,对相同版本或者MD5不再请求 2. manifest文件每次都会请求,我们可以按照一定时间更新一次,或者启动时更新一次,以减少manifest文件更新次数 3. 对hybrid方案还可以在打开app之前预缓存,提前下载文件或者更新manifest文件。