【问题标题】:Workbox SW: Runtime caching not working until second ReloadWorkbox SW:运行时缓存直到第二次重新加载才起作用
【发布时间】:2018-04-18 10:18:51
【问题描述】:

我是服务人员和工作箱的新手。我目前正在使用工作箱来预缓存我的静态资产文件,它工作正常,我希望我的其他第三方 URL 在运行时也被缓存,但直到我在页面上第二次重新加载时才工作:(

下面显示的是我的 Service Worker 的代码副本,请注意我故意替换了我原来的 abc.domain.com 链接:)

workbox.routing.registerRoute(
  //get resources from any abc.domain.com/
  new RegExp('^https://abc.(?:domain).com/(.*)'),
  /*
  *respond with a cached response if available, falling back to the network request if it’s not cached. 
  *The network request is then used to update the cache.
  */
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'Bill Resources',
    maxEntries: 60,
    maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
  }),
); 

workbox.routing.registerRoute(
  new RegExp('^https://fonts.(?:googleapis|gstatic).com/(.*)'),
  //serve from network first, if not availabe then cache
  workbox.strategies.networkFirst(),
); 

workbox.routing.registerRoute(
  new RegExp('^https://use.(?:fontawesome).com/(.*)'),
  //serve from network first, if not availabe then cache
  workbox.strategies.networkFirst(),
); 

我已经清除了无数的存储时间,我从谷歌开发者工具中刷新了缓存存储,但一切似乎都是一样的。来自自定义链接、google fonts 和 fontawesome 的资源第一次无法缓存。下面分别是我的页面第一次加载图像和第二次加载图像的控制台和缓存存储选项卡。

请我不知道我做错了什么以及为什么会这样。

提前致谢

【问题讨论】:

  • 阅读此内容可能会有所帮助,并且必须执行所有步骤 以刷新缓存。所以页面刷新可能是生命周期的特征......blog.sessionstack.com/…
  • Thanks@RobertRowntree,但我认为我的 Service Worker 已正确安装、注册和注册,它的行为仍然如此,并且控制台上没有打印错误消息

标签: caching progressive-web-apps workbox


【解决方案1】:

这是预期的行为。

Service Worker 的设置方式是他们将有一个安装和激活阶段,在此阶段,只要注册了新的 Service Worker 或更新了 Service Worker,就会进行安装。

Service Worker 将在安全的情况下激活(即当前没有任何窗口被“控制”为 Service Worker)。

一旦服务工作者被激活,它将控制任何新页面。

你看到的是:

  1. 页面已加载,页面注册了一个 service worker
  2. Service Worker 在其安装阶段预缓存所有文件
  3. 服务已激活但未控制任何页面
  4. 您刷新页面,此时页面被控制,请求将通过服务工作线程(导致第二次加载时缓存)。

【讨论】:

  • 感谢@GauntFace,我尝试在不使用工作箱的情况下编写自己的 JavaScript,尽管它在第一次加载时没有获取任何事件请求,直到第二次加载,然后我使用 self.clients.claim(),它获取首次加载时的事件。 self.addEventListener('install', function(event) { console.log('I am installed') }); self.addEventListener('fetch', function(event) { console.log("Fetching"+event.request) }); self.addEventListener('activate', function (event) { event.waitUntil(self.clients.claim()); }); 所以,我尝试将workbox.clientsClaim(); 用于工作箱,但它仍然无法正常工作。
  • 我希望服务人员在第一次加载时控制页面,因为当用户第一次访问我的网站时,我希望缓存外部 URL,以便在他们之后离线时第一次加载,所有外部链接都应该准备好并为它们加载。
  • 您不能让 SW 控制第一次加载,因为页面必须先加载才能注册 SW。您可能会发现不同的行为,因为您的示例没有像工作箱那样拉入任何文件。 clientsClaim() 将使 service worker 立即控制页面(即不刷新),但这将是 AFTER 页面已经加载,这意味着它不会看到请求。
【解决方案2】:

Service Worker 在被激活之前不会缓存任何内容。它仅在第二次命中时才被激活。要在第一次命中时实现缓存,您必须引导 service worker 跳过等待激活。你可以这样做

self.addEventListener('install', () => {
   self.skipWaiting(); //tells service worker to skip installing and activate it
   /*your code for pre-caching*/
});

一旦被跳过,它就会进入激活模式并等待缓存,但不会缓存客户端交互。为此,请应用以下行

self.addEventListener('activate', () => {
     clients.claim();
});

在第一次命中时开始缓存

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    相关资源
    最近更新 更多