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



故事

我有一个使用传统浏览器缓存的网站,该网站缓存量很大,静态内容长达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);

同样的行为仍然存在,就像软件集成之前一样。然而升级很慢,就像往常一样…


问题

我想知道是否有更好的方法它可以做下面这样的事情,并且仍然保留重缓存机制(对于旧浏览器):

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

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

这正是服务人员生命周期的工作方式。让我们以慢镜头观看:

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

现在,浏览器将发现有一个新的服务工作者,并将触发其install事件。在该处理程序中,打开新的缓存(以站点版本命名。例如:"cache-v" + version)并获取所有新资源。

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

现在,您的服务工作者已经准备好从新的缓存中获取。

这里的要点是:

  • 使用名称源自应用程序版本的缓存
  • 在安装过程中不使用self.skipWaiting()。通过这种方式,可以确保已安装的服务工作者继续为当前内容提供服务
  • 在服务人员中调用更新机器来更新版本

最新更新