Workbox-Getting Started

适用于 Workbox V5.1.2

Installation

Installation (CDN Mode)

其实很简单, 项目根目录放置一段 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()
);

Installation (Webpack Mode)

(TODO)

Cache Strategies

TLDR

使用 StaleWhileRevalidate() 策略

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

Detailed Explanation

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

  • Stale While Revalidate 优先使用缓存, 如果缓存存在则使用, 并且同时请求网络, 在后台更新缓存. 如果缓存不存在则要等待网络请求结束
  • Network First 先请求网如果网络成功则会加入缓存, 如果网络失败直接使用缓存
  • Cache First 先拦截请求, 并查看缓存, 如果返程存在则直接使用, 如果不存在则放行网络请求
  • Network Only (略)
  • Cache Only (略)

Implementation

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,
      }),
    ],
  }),
);

Troubleshooting

Uncaught ReferenceError: importScripts is not defined

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