我查阅了很多关于 Service Worker 的资源:
- 更新你的 ServiceWorker
- ServiceWorker:Web 平台的革命
- Jake Archibald 的可爱SVGOMG。
但是,在安装新的 ServiceWorker 后,我终生无法弄清楚如何更新页面。无论我做什么,我的页面都停留在旧版本上,只有硬刷新 (Cmd-Shift-R) 才能修复它。1) 关闭选项卡、2) 关闭 Chrome 或 3) 的任何组合都location.reload(true)
不会提供新内容。
我有一个超级简单的示例应用程序,主要基于 SVGOMG。在安装时,我使用 缓存了一堆资源,如果当前版本的主要版本号与活动版本号不匹配(基于 IndexedDB 查找)cache.addAll()
,我也会这样做:skipWaiting()
self.addEventListener('install', function install(event) {
event.waitUntil((async () => {
var activeVersionPromise = localForage.getItem('active-version');
var cache = await caches.open('cache-' + version);
await cache.addAll(staticContent);
var activeVersion = await activeVersionPromise;
if (!activeVersion ||
semver.parse(activeVersion).major === semver.parse(version).major) {
if (self.skipWaiting) { // wrapping in an if while Chrome 40 is still around
self.skipWaiting();
}
}
})());
});
我正在使用受 semver 启发的系统,其中主要版本号表明新的 ServiceWorker 不能热交换旧的。这适用于 ServiceWorker 方面 - 从 v1.0.0 到 v1.0.1 的碰撞会导致工作人员在刷新时立即安装,而从 v1.0.0 到 v2.0.0,它会等待选项卡关闭并重新打开之前安装。
回到主线程,我在注册后手动更新 ServiceWorker - 否则页面甚至不会得到有可用 ServiceWorker 的新版本的备忘录(奇怪的是,我发现在 ServiceWorker 文献中的任何地方都很少提到这一点):
navigator.serviceWorker.register('/sw-bundle.js', {
scope: './'
}).then(registration => {
if (typeof registration.update == 'function') {
registration.update();
}
});
但是,提供给主线程的内容总是停留在旧版本的页面上(“我的版本是 1.0.0”),无论我将版本增加到 1.0.1 还是 2.0.0。
我在这里有点难过。我希望为 ServiceWorker 版本控制找到一个优雅的 semver-y 解决方案(因此我使用require('./package.json').version
),但在我当前的实现中,用户永远停留在页面的旧版本上,除非他们硬刷新或手动清除所有他们的数据。:/