当前有两种离线缓存方式,一种是H5离线缓存,基于manifest,一种是基于 Service Worker。

manifest

其实manifest是一个简单的文本文件,它的扩展名是任意的,定义需要缓存的文件、资源,mime-type 为 text/cache-manifest 。
如: <html lang="en" manifest="index.manifest">

优点:

  • 离线浏览,无网情况下也能正常访问
  • 更快的加载速度,缓存在本地访问速度自然更快
  • 减轻服务请求压力,文件缓存后不需要再次请求,只需要请求需要更新的文件

manifest 文件可分为三个部分:

  • CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
  • NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
  • FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)

有三种方式更新manifest缓存:

  • 用户清空浏览器缓存
  • manifest文件被修改,哪怕是注释(所以可以通过修改注释来更新文件)
  • 由程序来更新
1
2
3
4
5
6
7
8
9
10
11
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();
window.location.reload();
} else {
// Manifest didn’t changed. Nothing new to server.
}

}, false);


1. 站点离线存储的容量限制是5M
2. 如果manifest文件,或者内部列举的某一个文件不能正常下载,整个更新过程将视为失败,浏览器继续全部使用老的缓存
3. 引用manifest的html必须与manifest文件同源,在同一个域下
4. 在manifest中使用的相对路径,相对参照物为manifest文件
5. CACHE MANIFEST字符串应在第一行,且必不可少
6. 系统会自动缓存引用清单文件的 HTML 文件
7. manifest文件中CACHE则与NETWORK,FALLBACK的位置顺序没有关系,如果是隐式声明需要在最前面
8. FALLBACK中的资源必须和manifest文件同源
9. 当一个资源被缓存后,该浏览器直接请求这个绝对路径也会访问缓存中的资源。
10. 站点中的其他页面即使没有设置manifest属性,请求的资源如果在缓存中也从缓存中访问
11. 当manifest文件发生改变时,资源请求本身也会触发更新

Service Worker

Service worker运行在worker上下文,因此它不能访问DOM。相对于驱动应用的主JavaScript线程,它运行在其他线程中,类似与 web worker, 所以不会造成阻塞。它设计为完全异步,同步API(如XHR和localStorage)不能在service worker中使用。

Service Worker 工作流程: register -> install -> activated ,可监听 install activated 过程事件,fetch message 操作,可实现请求劫持、代理、转发、伪造,消息推送,离线缓存。
依赖于HTTPS, 基于Promise,需要缓存Cache API, navigator.applicationCache.

使用场景:

  • 后台数据同步
  • 响应来自其它源的资源请求
  • 集中接收计算成本高的数据更新,比如地理位置和陀螺仪信息,这样多个页面就可以利用同一组数据
  • 在客户端进行CoffeeScript,LESS,CJS/AMD等模块编译和依赖管理(用于开发目的)
  • 后台服务钩子
  • 自定义模板用于特定URL模式
  • 性能增强,比如预取用户可能需要的资源,比如相册中的后面数张图片