工作框食谱

许多常见模式(尤其是路由缓存方面的常见模式)足够常见,可以标准化为可重复使用的配方。workbox-recipes 通过一个易于使用的软件包提供这些库,使您能够快速启动并运行功能强大的 Service Worker。

测试方案

每个方案都会将多个 Workbox 模块组合在一起,并将它们捆绑为常用模式。以下方案将展示您在使用此模块时所使用的方案,以及它在后台使用的等效模式(如果您想自己编写的话)。

离线后备广告

借助离线回退方案,如果这三个任务中的任何一个发生路由错误(例如,用户离线且没有缓存命中),您的 Service Worker 可以传送网页、图像或字体。在 Workbox Recipe 6.1.0 中,我们不再要求使用预缓存来缓存这些项;为了实现向后兼容性,它会先在预缓存中查找项,然后再尝试自己的缓存。

默认情况下,此方案假定后备页面为 offline.html,并且没有图片或字体回退。如需查看所有配置选项的列表,请参阅离线后备选项

仅当给定请求有匹配的路由时,系统才会应用离线回退。如果您单独使用离线后备配方,则需要自行创建路由。最简单的方法是使用 setDefaultHandler() 方法创建一个将 NetworkOnly 策略应用于所有请求的路由,如下所示。其他方案(例如页面缓存静态资源缓存图片缓存)则为其各自的缓存设置路由。如果同时使用离线后备和其中一个配方,则不需要 setDefaultHandler()

食谱

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

模式

import {setCatchHandler, setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

const pageFallback = 'offline.html';
const imageFallback = false;
const fontFallback = false;

setDefaultHandler(new NetworkOnly());

self.addEventListener('install', event => {
  const files = [pageFallback];
  if (imageFallback) {
    files.push(imageFallback);
  }
  if (fontFallback) {
    files.push(fontFallback);
  }

  event.waitUntil(
    self.caches
      .open('workbox-offline-fallbacks')
      .then(cache => cache.addAll(files))
  );
});

const handler = async options => {
  const dest = options.request.destination;
  const cache = await self.caches.open('workbox-offline-fallbacks');

  if (dest === 'document') {
    return (await cache.match(pageFallback)) || Response.error();
  }

  if (dest === 'image' && imageFallback !== false) {
    return (await cache.match(imageFallback)) || Response.error();
  }

  if (dest === 'font' && fontFallback !== false) {
    return (await cache.match(fontFallback)) || Response.error();
  }

  return Response.error();
};

setCatchHandler(handler);

温策略缓存

通过热策略缓存配方,您可以在 Service Worker 的 install 阶段将提供的网址加载到缓存中,并使用提供的策略选项缓存这些网址。如果您知道要缓存的具体网址、想要预热路线的缓存或在安装过程中缓存网址的类似位置,则可以将此方式用作预缓存的替代方案。

如需查看所有配置选项的列表,请参阅温策略缓存选项

食谱

import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';

// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = ['/offline.html'];

warmStrategyCache({urls, strategy});

模式

import {CacheFirst} from 'workbox-strategies';
// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = ['/offline.html'];

self.addEventListener('install', event => {
  // handleAll returns two promises, the second resolves after all items have been added to cache.
  const done = urls.map(
    path =>
      strategy.handleAll({
        event,
        request: new Request(path),
      })[1]
  );

  event.waitUntil(Promise.all(done));
});

网页缓存

借助页面缓存方案,您的 Service Worker 可以使用网络优先缓存策略(通过网址导航)响应对 HTML 页面的请求。理想情况下,该策略经过优化,可让缓存回退足够快速到达,从而实现不到 4.0 秒的 Largest Contentful Paint

默认情况下,此方案假定网络超时应为 3 秒,并且通过 warmCache 选项支持缓存预热。如需查看所有配置选项的列表,请参阅页面缓存选项

食谱

import {pageCache} from 'workbox-recipes';

pageCache();

模式

import {registerRoute} from 'workbox-routing';
import {NetworkFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cacheName = 'pages';
const matchCallback = ({request}) => request.mode === 'navigate';
const networkTimeoutSeconds = 3;

registerRoute(
  matchCallback,
  new NetworkFirst({
    networkTimeoutSeconds,
    cacheName,
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  })
);

静态资源缓存

借助静态资源缓存方案,您的 Service Worker 可以使用 stale-while-revalidate 缓存策略来响应静态资源请求,具体来说就是 CSS、JavaScript 和 Web Worker 请求,以便可以从缓存中快速提供这些资源并在后台进行更新

此配方支持通过 warmCache 选项进行缓存加热。如需查看所有配置选项的列表,请参阅静态资源缓存选项

食谱

import {staticResourceCache} from 'workbox-recipes';

staticResourceCache();

模式

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cacheName = 'static-resources';
const matchCallback = ({request}) =>
  // CSS
  request.destination === 'style' ||
  // JavaScript
  request.destination === 'script' ||
  // Web Workers
  request.destination === 'worker';

registerRoute(
  matchCallback,
  new StaleWhileRevalidate({
    cacheName,
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  })
);

图片缓存

借助图片缓存配方,您的 Service Worker 可以采用缓存优先缓存策略来响应图片请求,这样当图片在缓存中可用时,用户就无需再次为图片发出请求。

默认情况下,此配方最多可缓存 60 张图片,每张图片 30 天,并且通过 warmCache 选项支持缓存加热。如需查看所有配置选项的列表,请参阅图片缓存选项

食谱

import {imageCache} from 'workbox-recipes';

imageCache();

模式

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {ExpirationPlugin} from 'workbox-expiration';

const cacheName = 'images';
const matchCallback = ({request}) => request.destination === 'image';
const maxAgeSeconds = 30 * 24 * 60 * 60;
const maxEntries = 60;

registerRoute(
  matchCallback,
  new CacheFirst({
    cacheName,
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new ExpirationPlugin({
        maxEntries,
        maxAgeSeconds,
      }),
    ],
  })
);

Google Fonts 缓存

Google Fonts 配方会缓存 Google Fonts 请求的两个部分:

  • 包含 @font-face 定义的样式表,链接到字体文件。
  • 经过修改的静态字体文件。

由于样式表可能会经常更改,因此系统使用了 stale-while-revalidate 缓存策略。另一方面,字体文件本身不会改变,并且可以利用“缓存优先”策略。

默认情况下,此方案最多可以缓存 30 个字体文件,每个文件一年最多缓存 30 个。有关所有配置选项的列表,请参阅 Google Fonts 缓存选项

食谱

import {googleFontsCache} from 'workbox-recipes';

googleFontsCache();

模式

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {ExpirationPlugin} from 'workbox-expiration';

const sheetCacheName = 'google-fonts-stylesheets';
const fontCacheName = 'google-fonts-webfonts';
const maxAgeSeconds = 60 * 60 * 24 * 365;
const maxEntries = 30;

registerRoute(
  ({url}) => url.origin === 'https://fonts.googleapis.com',
  new StaleWhileRevalidate({
    cacheName: sheetCacheName,
  })
);

// Cache the underlying font files with a cache-first strategy for 1 year.
registerRoute(
  ({url}) => url.origin === 'https://fonts.gstatic.com',
  new CacheFirst({
    cacheName: fontCacheName,
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new ExpirationPlugin({
        maxAgeSeconds,
        maxEntries,
      }),
    ],
  })
);

快速使用

将所有配方组合在一起将产生一个 Service Worker,它采用网络优先缓存策略来响应页面请求,通过 stale-while-revalidate 策略响应 CSS、JavaScript 和 Web Worker 请求,使用缓存优先策略响应图片请求,正确缓存 Google Fonts,并为页面请求提供离线回退。所有这些操作都可以通过以下操作来实现:

import {
  pageCache,
  imageCache,
  staticResourceCache,
  googleFontsCache,
  offlineFallback,
} from 'workbox-recipes';

pageCache();

googleFontsCache();

staticResourceCache();

imageCache();

offlineFallback();

类型

GoogleFontCacheOptions

属性

  • cachePrefix

    字符串(可选)

  • maxAgeSeconds

    数字可选

  • maxEntries

    数字可选

ImageCacheOptions

属性

  • cacheName

    字符串(可选)

  • matchCallback
  • maxAgeSeconds

    数字可选

  • maxEntries

    数字可选

  • 插件

    WorkboxPlugin[] 可选

  • warmCache

    string[] 可选

OfflineFallbackOptions

属性

  • fontFallback

    字符串(可选)

  • imageFallback

    字符串(可选)

  • pageFallback

    字符串(可选)

PageCacheOptions

属性

  • cacheName

    字符串(可选)

  • matchCallback
  • networkTimeoutSeconds

    数字可选

  • 插件

    WorkboxPlugin[] 可选

  • warmCache

    string[] 可选

StaticResourceOptions

属性

WarmStrategyCacheOptions

属性

  • 策略
  • urls

    字符串[]

方法

googleFontsCache()

workbox-recipes.googleFontsCache(
  options?: GoogleFontCacheOptions,
)

[Google Fonts]https://developers.google.com/web/tools/workbox/guides/common-recipes#google_fonts 缓存方案的实现

参数

imageCache()

workbox-recipes.imageCache(
  options?: ImageCacheOptions,
)

[图片缓存方案]https://developers.google.com/web/tools/workbox/guides/common-recipes#caching_images 的实现

参数

offlineFallback()

workbox-recipes.offlineFallback(
  options?: OfflineFallbackOptions,
)

[全面后备方案]https://developers.google.com/web/tools/workbox/guides/advanced-recipes#comprehensive_fallbacks 的实现。请务必在预缓存注入中添加回退机制

参数

pageCache()

workbox-recipes.pageCache(
  options?: PageCacheOptions,
)

具有网络超时的网页缓存方案的实现

参数

staticResourceCache()

workbox-recipes.staticResourceCache(
  options?: StaticResourceOptions,
)

[CSS 和 JavaScript 文件诀窍]https://developers.google.com/web/tools/workbox/guides/common-recipes#cache_css_and_javascript_files的实现

参数

warmStrategyCache()

workbox-recipes.warmStrategyCache(
  options: WarmStrategyCacheOptions,
)