MDN 文档

  • ServiceWorker

参考文章

  • Working with the JavaScript Cache API

代码地址

指标

断网状况下失常关上页面,加载本地缓存数据

调试

chrome 控制台 > Application > Service Workers

创立 serviceWorker

新建 sw.js 文件,初始化监听事件:

//sw.js// 版本号const CACHE_VERSION = 'cache-v0'// 装置self.addEventListener('install', (event) => {    // sw.js 文件产生变动,就会执行 install 回调函数  console.log('install')})// 激活self.addEventListener('activate', (event) => {  console.log('activate')})// 捕捉网络申请self.addEventListener('fetch', (event) => {})

register

注册 serviceWorker:

navigator.serviceWorker.register("./sw.js",{scope:"/"}).then(    registration => console.log("success"),    error =>console.error("register error"))

waitUntil

sw.js 文件产生变动后,尽管会执行 install 回调函数,然而新版本的脚本文件并没有被激活。

激活 activate:

self.addEventListener('install', (event) => {  console.log('install')  //内容发生变化,间接进入 activate  event.waitUntil(self.skipWaiting());})

caches

存在全局的 caches 对象,可通过 caches.open(cacheName) 关上缓存对象或delete(cacheName) 删除对象。

通过 open 取得 Cache 次要蕴含以下几个办法:

api作用
Cache.addAll(requests)返回Promise,给 cache 增加缓存申请
Cache.match(request, options)返回Promise,匹配缓存对象已缓存申请
Cache.put(request, response)返回Promise,获取申请和保留响应后果
更具体的api介绍请查看 Working with the JavaScript Cache API

流程

ServiceWorker 须要在服务中启用

首页 index.html

  • 加载款式资源 index.css
  • 加载图片资源
  • 申请服务数据 data.json
  • 响应数据渲染进app标签
  • 注册 ServiceWorker 服务
<html>  <head>    <title>service Worker</title>    <link rel="stylesheet" href="./index.css" />  </head>  <body>    <div id="app"></div>    <img      src="https://blog.logrocket.com/wp-content/uploads/2020/06/cacheapi.png"    />    <script>      ;(async () => {        const registration = await navigator.serviceWorker.register('./sw.js', {          scope: '/',        })      })()      window.onload = function () {        const xhr = new XMLHttpRequest()        xhr.open('GET', './data.json')        xhr.responseType = 'json'        xhr.onload = () => {          app.innerText = xhr.response.result        }        xhr.send(null)      }    </script>  </body></html>

sw.js 流程

  • 申明版本号

install

  • 取得对应版本号cache
  • 增加须要缓存的资源门路
  • 进入 activate

activate

  • 取得曾经注册的caches版本
  • 遍历版本号,比照以后最新版本号
  • 新旧版本号不匹配,清空旧版本

fetch

  • 截取申请资源
  • 关上以后版本号的缓存资源
  • 匹配到缓存后果返回
  • 不在缓存的资源再fetch服务器资源
  • 如果是图片资源,退出到缓存
// sw.jsconst CACHE_VERSION = 'cache-v0'// 只有 sw.js 发生变化,就会执行 installself.addEventListener('install', (event) => {  console.log('install')  //内容发生变化,间接进入 activate  // event.waitUntil(self.skipWaiting());  // 进入缓存,增加缓存资源门路,接着进入 activate  event.waitUntil(    caches      .open(CACHE_VERSION)      .then((cache) => cache.addAll(['/', '/index.css']))      .then(self.skipWaiting)  )})self.addEventListener('activate', (event) => {  console.log('activate')  // 默认状况下,首次加载后不受管制,self.clients.claim 让首次管制失效  // event.waitUntil(self.clients.claim())  // 判断缓存资源,如果缓存版本批改,删掉旧版本资源  event.waitUntil(    caches.keys().then((cahceNames) => {      return Promise.all(        cahceNames.map((cacheName) => {          if (cacheName !== CACHE_VERSION) {            console.log('clear', cacheName)            return caches.delete(cacheName)          }        })      )    })  )})self.addEventListener('fetch', (event) => {  const url = event.request.url  event.respondWith(    caches.open(CACHE_VERSION).then(async (cache) => {      // 匹配缓存中的申请资源      let response = await cache.match(event.request)      // 存在则返回      if (response) return response      // 否则申请服务器资源      response = await fetch(event.request)      // 缓存服务器资源      if (/\.(jpg|png)$/g.test(url)) {        cache.put(event.request, response.clone())      }      return response    })  )})