[学习] Service Worker 既要缓存,也要最新

1,769 阅读1分钟

Service Worker 是什么

Service Worker 本质上是一个代理服务器,它可以拦截请求并做相应处理,可以直接返回缓存,也可以向服务器发起请求,还能通信、后台同步等。

image.png

Service Worker 可以让应用先访问本地缓存资源,所以借助 Service Worker 可以搭建离线可用的 Web App。将请求加入缓存有两种方法:在安装时添加(指定请求);在请求真正发生时添加(任意请求)。

使用 Service Worker

接下来利用 Service Worker 实现这样的功能:对所有请求,先返回缓存资源,保证页面迅速展现,同时发起网络请求更新缓存,保证缓存是新的,但有个缺陷,如果数据更新了,需要多刷新一次才能看到新数据。

index.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker
    .register('sw.js')
    .then(function(reg) {
      // registration worked
    })
    .catch(function(error) {
      // registration failed
    })
}

sw.js

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('v1').then(cache => {
      // 安装时添加缓存,指定请求
      return cache.addAll(['/a', '/b'])
    })
  )
})

self.addEventListener('fetch', event => {
  if (event.request.url.indexOf('http') !== 0) return
  event.respondWith(
    caches.match(event.request).then(matchCache => {
      // 请求发生时添加缓存,任意请求
      fetch(event.request).then(response => {
        caches.open('v1').then(function(cache) {
          cache.put(event.request, response)
        })
      })
      return matchCache || fetch(event.request)
    })
  )
})

install 事件不是必须的,它可在首次访问时缓存指定路径资源,但仍需监听 fetch 事件来响应缓存。

fetch 事件拦截页面所有请求,如果没有在 install 事件指定缓存某请求,那该请求在页面第二次加载时才缓存,第三次加载才可访问缓存。