服务工作者JavaScript更新频率(每24小时?)

78
根据MDN 上的文档,每隔大约 24 小时会下载一次服务工作者脚本。它可能会更频繁地下载,但必须每隔 24 小时下载一次以防止糟糕的脚本太长时间地干扰。Firefox 和 Chrome 是相同的吗?还是只有当用户访问站点时才更新服务工作者 JavaScript?
2个回答

192

注意:自Firefox版本57Chrome版本68以及支持服务工作者的Safari和Edge版本,其默认行为已更改以适应更新的服务工作者规范。在这些浏览器中,默认情况下将忽略HTTP缓存指令来检查服务工作者脚本是否需要更新。下面的描述仍适用于早期版本的Chrome和Firefox。

每当您导航到服务工作者范围内的新页面时,Chrome会对传递给navigator.serviceWorker.register()调用的JavaScript资源进行标准HTTP请求。我们假设它的名字是service-worker.js。只有在导航或通过例如push事件唤醒服务工作者时才会发出此请求。没有后台进程每24小时重新获取每个服务工作者脚本,也没有任何自动化操作。

这个HTTP请求将遵循标准的HTTP缓存指令,但有一个例外情况(在下一段中会讲到)。例如,如果您的服务器设置了适当的HTTP响应头,指示缓存响应应该使用1小时,则在接下来的1小时内,浏览器对service-worker.js的请求将由浏览器缓存满足。请注意,我们并不是在谈论Cache Storage API,它在这种情况下不相关,而是标准浏览器HTTP缓存
唯一例外的是标准HTTP缓存规则,这就是24小时的原因,如果HTTP缓存中service-worker.js条目的年龄大于24小时,浏览器将始终访问网络。因此,在功能上,使用1天、1周或1年的max-age没有区别,它们都将被视为max-age为1天。
浏览器厂商希望确保开发人员不会意外发布一个带有1年max-age的“损坏”或有错误的service-worker.js,从而使用户长时间拥有可能是持久的、有错误的Web体验。(您不能指望用户知道清除站点数据或按Shift键刷新站点。)
有些开发者喜欢使用响应头明确地提供service-worker.js,以禁用所有HTTP缓存,这意味着每次导航都会发出一个service-worker.js的网络请求。另一种方法可能是使用非常短的max-age——比如一分钟——以提供一定程度的节流,以防单个用户进行大量快速导航。如果您真的想最小化请求并且确信不会很快更新service-worker.js,则可以将max-age设置为24小时,但我建议在意外需要重新部署的情况下使用更短的时间。保留HTML标签。

2
感谢Jeff的清晰解释,解决了所有疑问。 - shailesh mishra
1
如果在fetch和缓存中拦截了service-worker调用,会发生什么?这样做是否也会在一天后过期。 - Pankaj
3
当页面请求服务工作者脚本进行注册时,服务工作者的fetch事件处理程序不会被触发。 - Jeff Posnick
6
如果将max-age视为1天,那么所有内容都将被视为同样的处理方式。这是否完全颠覆了服务工作者的初衷?如果我的应用与互联网断开连接24小时,它就会停止工作,我无能为力吗?这一切只是为了让用户不必知道如何清除他们的缓存,或者让开发人员在URL中添加一个缓存破坏器。我有什么遗漏的吗? - Simon
9
“如果我的应用在断网24小时后就无法工作”是不正确的表述。您之前缓存过的内容和服务工作线程JS文件会在离线时继续使用。本文详细介绍了您处于“在线状态”下的情况,以及更新检查的频率。 - Jeff Posnick
显示剩余3条评论

0
一些开发者更喜欢明确地使用响应头来提供他们的`service-worker.js`,从而禁用所有HTTP缓存,这意味着在每次导航时都会为`service-worker.js`进行网络请求。
这种“无缓存”策略在快节奏的“敏捷”环境中可能很有用。
以下是实现方法:
只需将以下隐藏的`.htaccess`文件放置在包含`service-worker.js`的服务器目录中:
# DISABLE CACHING
<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

<FilesMatch "\.(html|js)$">
    <IfModule mod_expires.c>
        ExpiresActive Off
    </IfModule>
    <IfModule mod_headers.c>
        FileETag None
        Header unset ETag
        Header unset Pragma
        Header unset Cache-Control
        Header unset Last-Modified
        Header set Pragma "no-cache"
        Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
        Header set Expires "Thu, 1 Jan 1970 00:00:00 GMT"
    </IfModule>
</FilesMatch>

这将禁用此服务器目录及其子目录中所有.js.html文件的缓存,而不仅仅是service-worker.js

只选择了这两种文件类型,因为它们是我的PWA的非静态文件,可能会影响在浏览器窗口中运行应用程序的用户(尚未)安装为全自动更新的PWA。

有关服务工作程序行为的更多详细信息,请参见Google Web Fundamentals


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接