【问题标题】:Workbox - runtime cache only created on second page refreshWorkbox - 运行时缓存仅在第二个页面刷新时创建
【发布时间】:2018-01-21 14:34:50
【问题描述】:

我是服务工作者的新手,我正在使用 Workbox 预缓存我的应用程序外壳并缓存我的 api 数据。

资产的预缓存工作正常,缓存正在创建和填充。

在我第二次重新加载页面之前,运行时缓存不会创建缓存并填充它。

我认为这可能是时间问题,所以我在 javascript 中设置了数据的页面重新加载,但这仍然没有缓存调用。

我没有做任何特定于创建缓存的事情,应用代码是:

...
app.getData = function() {
  var requestHeaders = new Headers({
    Accept: "application/json"
  });
  fetch(app.dataUrl, { headers: requestHeaders })
  .then(function(response) {
    return response.json();
  })
  .then(function(json) {
      app.updateCards(json);
  })
  .catch(function(error) {
      console.log('There has been a problem with your fetch operation: ' + error.message);
  });
}
...
if ('serviceWorker' in navigator) {
navigator.serviceWorker
         .register('/my_sw.js')
         .then(function() {
            console.log('Service Worker Registered');
         });
}

app.getData();  # fetch api data

然后在服务工作者中:

 ...
 const workboxSW = new self.WorkboxSW({clientsClaim: true});
 // register data url to cache
 workboxSW.router.registerRoute(
    '/my_api/data',
     workboxSW.strategies.staleWhileRevalidate()
 );
 // pre-cache assets
 workboxSW.precache(fileManifest);

我正在使用 Chrome 开发工具来检查 sw 状态和创建的缓存。对数据URL的网络调用如下:

第一次加载页面:
第二次加载页面:

对于我做错了什么或如何调试它的任何建议,我将不胜感激。

提前致谢

【问题讨论】:

  • 我没有看到您的设置有任何明显不正确的地方。您如何确认运行时缓存(重新加载后)不起作用? Chrome DevTool 的应用程序面板中的缓存存储查看器有时会显示过时的数据,我想知道这对您来说是否是个问题。此外,请参阅stackoverflow.com/questions/33590378/…,了解如果 SW 拦截了您的 API 请求,您应该在 Network 面板中看到什么。最后,是否有一个我们可以访问并自己测试的 URL?
  • @JeffPosnick 感谢您的建议。我在 devtool 的 Application 选项卡上使用 Clear Storage 来清除所有内容,然后使用“空缓存和硬重新加载”加载页面。页面加载,我的 api 被调用并且数据出现在页面上(见上面的编辑),我右键单击缓存存储并刷新它 - 只出现一个缓存“workbox-precaching..”。我通过正常刷新刷新页面,刷新缓存存储,并且列出了预缓存和运行时缓存。我在上面的编辑中添加了网络调用的详细信息。
  • @JeffPosnick 我已经向您发送了 Twitter 上一个示例的链接。
  • 一些事情:服务工作者不控制通过“硬重新加载”加载的页面。使用clientsClaim 意味着您的服务工作者将在 SW activates 后立即控制页面,但激活发生确实需要时间(它必须首先完成install 步骤)。如果您的 API 请求是在 SW 获得控制权之前发出的,那么在后续访问之前,它不会被拾取和缓存。我访问了您的站点并确认在第二次访问时,没有硬重新加载,运行时缓存已被填充。
  • window.caches.open('my-cache').then(cache => cache.add(requestUrl)); 你的页面应该这样做。设置 SW 策略时,请使用 workboxSW.strategies.staleWhileRevalidate({cacheName: 'my-cache'});,以便它使用相同的缓存。

标签: api caching workbox


【解决方案1】:

为了安全起见,您可能需要将 skipWaiting 添加到 Workbox 构造函数中,以确保服务工作者不会等待页面重新加载以开始缓存。

在进行 API 调用之前,您还需要等待页面中的 serviceWorker.ready。这样你就知道 service worker 是活跃的。

这些变化一起,在你的服务工作者中你会拥有:

 ...
 const workboxSW = new self.WorkboxSW({skipWaiting: true, clientsClaim: true});
 // register data url to cache
 workboxSW.router.registerRoute(
    '/my_api/data',
     workboxSW.strategies.staleWhileRevalidate()
 );
 // pre-cache assets
 workboxSW.precache(fileManifest);

然后在你的网页中

...
if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('/my_sw.js')
      .then(function() {
        return navigator.serviceWorker.ready;
      })
      .then(function() {
        app.getData();  # fetch api data
      });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多