如何缓存 bust sw-toolbox?

How to cache bust sw-toolbox?

我一直在研究 service worker 和 sw-toolbox。两者都是很好的方法,但似乎都有其缺点。

我的项目开始使用 Google 的服务工作者方法 (link)。我的看法是您必须手动更新版本号以清除缓存。我也可能是错的,但我认为用户访问过的页面不会被缓存。

相比sw-toolbox方法,我只需要添加如下代码:

self.toolbox.router.default = self.toolbox.networkFirst;

self.toolbox.router.get('/(.*)', function (req, vals, opts) {
    return self.toolbox.networkFirst(req, vals, opts)
        .catch(function (error) {
            if (req.method === 'GET' && req.headers.get('accept').includes('text/html')) {
                return self.toolbox.cacheOnly(new Request(OFFLINE_URL), vals, opts);
            }
            throw error;
        });
});

那么缓存页面的问题就解决了。这是我的问题:将 sw-toolbox 应用到我的项目后,旧的 service worker 不会被清除或被新的 service worker 替换,除非我去开发工具清除它。

有什么办法解决这个问题吗?

我不知道 sw_toolbox 是否内置了缓存清除功能。通常,当您更改服务工作者并需要清除以前版本的缓存时,您应该在激活事件处理程序中执行此操作。

此处的最佳做法是使用包含 sw 版本号的名称来命名缓存。以下是我开设的关于服务工作者缓存的在线课程中的一些示例代码,可以帮助您入门:

self.addEventListener("activate", event => {

console.log("service worker activated");

//on activate
event.waitUntil(caches.keys()
    .then(function (cacheNames) {

        cacheNames.forEach(function (value) {

            if (value.indexOf(config.version) < 0) {

                caches.delete(value);

            }

        });

        return;

    })
);

});

Here is my issue: after applying the sw-toolbox to my project, the old service worker doesn't get cleared or replaced by the new one unless I go to the dev tools to clear it.

浏览器每次请求服务工作者范围内的资源时都会检查服务工作者文件的更新。如果 service worker 文件中存在字节差异,浏览器将安装新的 service worker。您只需要在开发工具中手动更新 service worker,因为该应用程序仍然 运行,并且浏览器不希望在旧的 service worker 仍在使用时激活新的 service worker。

如果您关闭所有与 Service Worker 关联的页面(就像用户在离开您的应用程序时所做的那样),浏览器将能够在您的页面下次打开时激活新的 Service Worker。

如果想强制让新的service worker接管,可以在install事件中添加self.skipWaiting();Here is some documentation with an example.

您可以从 this post by Jake Arichbald.

中了解有关 Service Worker 生命周期的几乎所有信息

就缓存和缓存管理而言,sw-toolbox 等工具将为您处理缓存破坏。实际上,Workbox 是一个旨在取代 sw-toolbox 和 sw-precache 的新工具。它还将处理缓存清除和缓存管理(通过比较文件哈希和 setting/tracking 资源到期日期)。

一般来说,您应该始终使用 Workbox 这样的工具来编写您的服务人员。手写它们很容易出错,而且您很可能会错过边角案例。

希望对您有所帮助。

P.S。如果您最终不使用 skipWaiting 而是仅在页面关闭和用户重新打开时更新,您仍然可以为开发启用自动更新。在 Chrome 的开发工具中,Application > Service Workers 有一个 Update on reload 选项来自动更新 service worker。