适用于 Workbox V5.1.2

其实很简单, 项目根目录放置一段 service-worker 的入口:

if ('serviceWorker' in navigator) {
  // Use the window load event to keep the page load performant
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('service-worker.js');
  });
}

然后新建一个文件 service-worker.js , 你们可以写上一个最简单的 registerRoute 方法:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');

const {
  registerRoute
} = workbox.routing;
const {
  CacheFirst
} = workbox.strategies;
const {
  CacheableResponse
} = workbox.cacheableResponse;

registerRoute(
  new RegExp('.*.css'),
  new CacheFirst()
);

(TODO)

使用 StaleWhileRevalidate() 策略

registerRoute(
  new RegExp('\.(jpg|gif|bmg|png|jpeg|gif|ico)'),
  new StaleWhileRevalidate(),
);

workbox-strategies 这个库会暴露几个方法, 其中主要关注以下几个方法:

  • Stale While Revalidate

优先使用缓存, 如果缓存存在则使用, 并且同时请求网络, 在后台更新缓存. 如果缓存不存在则要等待网络请求结束

  • Network First

先请求网如果网络成功则会加入缓存, 如果网络失败直接使用缓存

  • Cache First

先拦截请求, 并查看缓存, 如果返程存在则直接使用, 如果不存在则放行网络请求

  • Network Only

(略)

  • Cache Only

(略)

importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');

const {
  registerRoute
} = workbox.routing;
const {
  StaleWhileRevalidate
} = workbox.strategies;
const {
  CacheableResponsePlugin
} = workbox.cacheableResponse;
const {
  ExpirationPlugin
} = workbox.expiration;

/* cache js and css, use StaleWhileRevalidate strategy  */
registerRoute(
  ({
    request
  }) => request.destination === 'script' ||
  request.destination === 'style',
  new StaleWhileRevalidate({
    cacheName: 'notebook/cache/jsAndCss',
  }),
);

/* Cache pic for 180 days */
registerRoute(
  new RegExp('\.(jpg|gif|bmg|png|jpeg|gif)'),
  new StaleWhileRevalidate({
    cacheName: 'notebook/cache/image',
    plugins: [
      new ExpirationPlugin({
        maxAgeSeconds: 60 * 60 * 24 * 180,
        maxEntries: 30,
      }),
    ],
  }),
);

/* cache font for 1 year */
registerRoute(
  new RegExp('\.(woff|woff2|tff|ico)'),
  new StaleWhileRevalidate({
    cacheName: 'notebook/cache/fontAndIcon',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new ExpirationPlugin({
        maxAgeSeconds: 60 * 60 * 24 * 365,
        maxEntries: 30,
      }),
    ],
  }),
);

importScripts 方法只能放在 service-worker 里面执行

这个是因为 importScripts 只有在 worker 这个 object 的 context 中才能执行.

需要将 importScripts 方法放置在 navigator.serviceWorker.register('xxx.js'); 这一行这里注册的 xxx.js 这个 service-worker 里面执行

Reference: https://stackoverflow.com/questions/14500091/uncaught-referenceerror-importscripts-is-not-defined#answer-28620642