在大量缓存站点上使用查询字符串版本标识符的 Service Worker 的最佳方法

Best approach of Service Worker with query string version identifier on a heavy cached site

故事

我有一个使用传统浏览器缓存的网站,网站缓存很重,静态内容长达 365 天。

为了在部署新版本后清除缓存,我使用了版本标识符的查询字符串,例如:

<script src="js/main.js?version=1.3.0"></script>

但是对于每次版本升级,加载时间都很糟糕,因为浏览器需要在查询字符串更改时下载所有新内容。


情况

现在,我们有了 Service Worker,我已经将它集成到我的网站中。到目前为止一切正常,版本标识符的查询字符串仍然可以使用。

// simply cache all the static contents
global.toolbox.router.get('/', global.toolbox.networkFirst); 
global.toolbox.router.get(/(.js|.css|.png|.jpg|.json|.html)/, global.toolbox.fastest);

并且与 SW 集成之前相同的行为仍然存在。然而升级一如既往地缓慢...


问题

我想知道是否有更好的方法? 可以做类似下面的事情并且仍然保留大量缓存机制(对于旧浏览器):

  1. 找到新版本
  2. 仍然使用最新版本的旧内容,
  3. 正在获取新版本的所有新内容,
  4. 下次用户访问该站点时,他们将使用最新版本。

注意目标是在部署新版本时更快地加载站点

那是 exactly how service workers' life cycle work。让我们慢镜头来看:

首先,您需要字节级更改服务工作者以强制更新它:您可以包含应用程序的版本并将其存储在变量中 var version = "1.0.0"

现在浏览器会发现有一个新的 service worker 并且会触发它的 install 事件。在该处理程序中,打开您的新缓存(以您的站点版本命名。例如:"cache-v" + version)并获取所有新资源。

在关闭由前服务工作者控制的最后一个选项卡之前,新服务工作者不会被激活。关闭所有选项卡并重新打开应用程序后,new service worker 将收到 activate 事件。在此处理程序中,您可以删除过时的缓存。

现在您的 service worker 已准备好从新缓存中获取。

这里的要点是:

  • 使用名称源自应用程序版本的缓存。
  • 在安装期间不使用 self.skipWaiting()。通过这种方式,您可以确保已安装的 Service Worker 继续提供当前内容。
  • 在 service worker 中更新版本以调用更新机器。