如何强制服务人员更新



我使用sw-precache生成带有Polymer CLI构建过程的服务工作,因此它旨在更新更新文件的哈希,以表示需要更新缓存。但我更新的内容并没有在缓存中被替换,所以如果我用ctrl+r刷新,它会得到一个旧版本,但如果我用trl+shift+r刷新,它就会得到新版本。原因可能是我的服务人员没有得到更新。

该文件指出

如果服务工作者文件中甚至有一个字节的差异与目前相比,它认为这是新的。

,但是如果我的新服务人员没有更改一个字节呢?(如果只更改了一个散列,就会发生这种情况)。如何配置软件预缓存以在每次新请求时更新服务工作?

正如前面的回答所述,浏览器为服务工作者查找更新有一个内置的1天(24小时)限制,但您需要注意的是,您仍然需要在ServiceWorkerRegistration对象上调用.update(),否则将使用文件的原始版本。

在Chrome中测试更改时,在使用service worker脚本时,我总是右键单击刷新按钮并选择"空缓存和硬重置"(当开发人员工具打开时,选项可用)。

"w-precache"已被Workbox取代,Workbox为您想要预缓存的文件生成哈希,并将其添加到服务人员的源代码中(我不知道sw-precache是否以同样的方式工作,Jeff的回答表明是这样)。如果您想要预缓存的任何文件发生了更改,并且您重新运行了构建,则会更新服务工作者中更新的哈希,这几乎可以保证服务工作者"至少有一个字节不同"。

当您重新加载(ctrl-r)或重新访问您的应用程序时,浏览器将再次获取为其注册的服务工作者。如果该服务工作者已更改,它将"排队"管理应用程序。但它不会开始管理应用程序,直到你在应用程序打开的情况下关闭所有选项卡,然后打开一个新的选项卡。

当你硬刷新(shift-ctrl-r)时,它总是在没有控制器的情况下加载,这与使用新的服务工作者不同。

为了在开发过程中进行测试,我在devtools中使用跳过等待,使新的服务工作者替换旧的服务工作者,而无需等待我关闭所有选项卡。

如果一个文件的哈希发生了更改,则足以确保sw-precache生成的服务工作者JavaScript文件发生更改。反过来,这就足以触发服务工作者更新流。

如果您在测试时没有看到触发的更新流,那么这可能是由于服务工作者JavaScript文件带有HTTP缓存头,导致它是从浏览器的缓存而不是从网络中获取的。

请参阅https://stackoverflow.com/a/38854905/385997讨论HTTP缓存头是如何发挥作用的,以及与此相关的最佳实践。

我从用户体验的角度实现的一个选项是在服务工作者上调用unregister方法。(https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/unregister)

一旦注销过程完成,您可以:

  1. 强制刷新窗口(window.location.reload)
  2. 根据您的加载过程,您可以获取新的服务工作者,它有望缓存您的所有新内容

我以前遇到过服务工作者的奇怪问题,因此这种类型的解决方案允许您在一定程度上清除旧缓存并刷新应用程序的状态,而无需强迫用户清除他们的实际浏览器缓存,同时重新加载应用程序。

EX(如何注销):

serviceworker.unregister()
.then( unregResult => { 
//You can check if successful with Promise result 'unregResult'
window.location.reload();
})

service‑worker.js中存储版本号

控制service-worker.js中的一个字符更改将自动触发PWA更新。因此,如果将版本号存储在此文件中的const中并对其进行更改,则会触发PWA的更新。

最终如何处理更新由service-worker.js决定。可以根据PWA资产的规模和波动性来定义不同的更新策略。

然而,有一个重要的警告请确保资产服务器上的.htaccess文件设置的浏览器缓存过期指令设置为非常短的持续时间(例如hours),甚至设置为。否则,浏览器将在未来几天内看不到manifest.jsonservice-worker.js的任何更改。

有关服务人员行为的更多详细信息,请访问GoogleWebFundamentals。

const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
//Force the Service Worker to Upddate
self.registration.update();
const notification = JSON.parse(payload.data.notification);
return self.registration.showNotification(notification.title, notification);
});

相关内容

  • 没有找到相关文章

最新更新