【问题标题】:Workbox cache group is not correct工作箱缓存组不正确
【发布时间】:2020-05-21 23:47:19
【问题描述】:

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

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-v1js-cache-v1。但是,20 次中有 1 次显示正确的缓存组,我就是不知道为什么。
  • Google 字体从内存缓存中显示。这是正确的吗?它在离线状态下工作正常,但如果用户关闭浏览器/机器并返回离线模式会发生什么?
  • “/app-shell.html”的用法是否正确?它是一个快速后端应用程序,其中 * 作为所有路由的通配符,React Router 处理路由。从功能上讲,它可以离线工作。我没有任何 app-shell.html 页面。

感谢您的帮助。

【问题讨论】:

    标签: caching workbox workbox-webpack-plugin


    【解决方案1】:

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

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

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

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

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

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

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

    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 的内容,部署您的应用程序的新版本,但您的用户仍会看到旧版本,因为您忘记了更新revision: 'html-cache-1'。一般来说,最好使用在构建步骤中生成的修订。

    【讨论】:

    • 嗨@Philip,感谢您的回复。我有一些后续问题。不幸的是,stackoverflow 没有允许足够的字符(也许,这只是对像我这样的新用户的限制),所以我将它发布在 GitHub 上。有机会可以看看吗?谢谢。 github.com/GoogleChrome/workbox/issues/…
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多