1

我正在使用带有 InjectManifest 插件的 workbox-webpack-plugin v5(最新版本)。以下是我的服务工作者源文件:

import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { clientsClaim, setCacheNameDetails, skipWaiting } from 'workbox-core';
import { ExpirationPlugin } from 'workbox-expiration';
import {
  cleanupOutdatedCaches,
  createHandlerBoundToURL,
  precacheAndRoute,
} from 'workbox-precaching';
import { NavigationRoute, registerRoute, setCatchHandler } from 'workbox-routing';
import { CacheFirst, NetworkOnly, StaleWhileRevalidate } from 'workbox-strategies';

setCacheNameDetails({
  precache: 'install-time',
  prefix: 'app-precache',
  runtime: 'run-time',
  suffix: 'v1',
});

cleanupOutdatedCaches();

clientsClaim();

skipWaiting();

precacheAndRoute(self.__WB_MANIFEST);

precacheAndRoute([{ url: '/app-shell.html', revision: 'html-cache-1' }], {
  cleanUrls: false,
});

const handler = createHandlerBoundToURL('/app-shell.html');

const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);


registerRoute(
  /.*\.css/,
  new CacheFirst({
    cacheName: 'css-cache-v1',
  })
);


registerRoute(
  /^https:\/\/fonts\.(?:googleapis|gstatic)\.com/,
  new CacheFirst({
    cacheName: 'google-fonts-cache-v1',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
      new ExpirationPlugin({
        maxAgeSeconds: 60 * 60 * 24 * 365,
        maxEntries: 30,
      }),
    ],
  })
);


registerRoute(
  /.*\.js/,
  new StaleWhileRevalidate({
    cacheName: 'js-cache-v1',
  })
);


setCatchHandler(new NetworkOnly());

我有以下问题/问题:

  • 缓存组不正确。除了 google 字体之外的所有内容都在workbox-precache-v2app-precache-install-time-v1缓存组下,而不是单个缓存组,例如css-cache-v1, js-cache-v1. 但是,20 次中有 1 次显示正确的缓存组,我就是不知道为什么。
  • 谷歌字体从内存缓存中显示。这是对的吗?它在离线状态下工作正常,但如果用户关闭浏览器/机器并返回离线模式会发生什么?
  • '/app-shell.html' 的用法正确吗?它是一个快速后端应用程序,其中 * 作为所有路由的通配符,React Router 处理路由。从功能上讲,它可以离线工作。我没有任何 app-shell.html 页面。

谢谢你的帮助。

4

1 回答 1

0

缓存组不正确。除了 google 字体之外的所有内容都在workbox-precache-v2app-precache-install-time-v1缓存组下,而不是单个缓存组,例如css-cache-v1, js-cache-v1. 但是,20 次中有 1 次显示正确的缓存组,我就是不知道为什么。

这取决于你的预缓存清单中的内容(即self.__WB_MANIFEST在你的 webpack 构建期间被替换的内容)。

例如,假设您有一个由 webpack 生成的名为 的文件bundle.js,该文件最终出现在您的预缓存清单中。根据你的 service worker 代码,该文件最终会在一个缓存中调用app-precache-install-time-v1——即使它也将你的运行时路由与缓存相匹配js-cache-v1

原因是您的预缓存路由是在运行时路由之前注册的,因此您的预缓存逻辑将处理该请求,而不是您的运行时缓存逻辑。

谷歌字体从内存缓存中显示。这是对的吗?它在离线状态下工作正常,但如果用户关闭浏览器/机器并返回离线模式会发生什么?

我相信这意味着服务工作者没有处理请求,但您可以检查开发人员控制台中的工作箱日志以进行验证(看看为什么不处理)。

或者,您可以更新代码以使用自定义处理程序,该处理程序只记录它是否像这样运行:

registerRoute(
  /^https:\/\/fonts\.(?:googleapis|gstatic)\.com/,
  ({request}) => {
    // Log to make sure this function is being called...
    console.log(request.url);
    return fetch(request);
  }
);

'/app-shell.html' 的用法正确吗?它是一个快速后端应用程序,其中 * 作为所有路由的通配符,React Router 处理路由。从功能上讲,它可以离线工作。我没有任何 app-shell.html 页面。

您的快速路线是否响应名为 的文件app-shell.html?如果是这样,那么您可能希望您的预缓存修订是文件本身的哈希(而不是revision: 'html-cache-1')。您现在拥有的应该可以工作,但风险是您将更改 的内容app-shell.html,部署应用程序的新版本,但您的用户仍会看到旧版本,因为您忘记了 update revision: 'html-cache-1'。一般来说,最好使用作为构建步骤的一部分生成的修订。

于 2020-02-06T23:57:47.970 回答