故事
我有一个使用传统浏览器缓存的网站,该网站缓存量很大,静态内容长达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);
同样的行为仍然存在,就像软件集成之前一样。然而升级很慢,就像往常一样…
问题
我想知道是否有更好的方法它可以做下面这样的事情,并且仍然保留重缓存机制(对于旧浏览器):
- 找到新版本
- 仍然使用最新版本的旧内容
- 在获取新版本的所有新内容的情况下
- 下次用户访问该网站时,他们将使用最新版本
注意目标是在部署新版本时更快地加载站点
这正是服务人员生命周期的工作方式。让我们以慢镜头观看:
首先,您需要对服务工作者进行字节级更改,以强制更新它:您可以包含应用程序的版本,并将其存储在变量var version = "1.0.0"
中。
现在,浏览器将发现有一个新的服务工作者,并将触发其install
事件。在该处理程序中,打开新的缓存(以站点版本命名。例如:"cache-v" + version
)并获取所有新资源。
在关闭由前服务工作者控制的最后一个选项卡之前,新服务工作者不会被激活。关闭所有选项卡并重新打开应用程序后,新服务工作者将收到activate
事件。在这个处理程序中,您可以删除过时的缓存。
现在,您的服务工作者已经准备好从新的缓存中获取。
这里的要点是:
- 使用名称源自应用程序版本的缓存
- 在安装过程中不使用
self.skipWaiting()
。通过这种方式,可以确保已安装的服务工作者继续为当前内容提供服务 - 在服务人员中调用更新机器来更新版本