本代码实验室将向您展示如何从 Web 应用程序中注册 Service Worker,以及如何使用 Chrome DevTools 观察其行为。它还介绍了一些在处理 Service Worker 时可能会发现有用的调试技巧。
熟悉示例项目
本代码实验室中最相关的示例项目文件是
register-sw.js
最初是空的,但它将包含用于注册 Service Worker 的代码。它已经通过项目index.html
内的<script>
标记加载。service-worker.js
同样是空的。它是将包含此项目的 Service Worker 的文件。
添加 Service Worker 注册代码
Service Worker(即使是像当前的 service-worker.js
文件这样的空文件)也不会被使用,除非先注册它。您可以通过调用以下代码来完成此操作
navigator.serviceWorker.register(
'/service-worker.js'
)
在您的 register-sw.js
文件中。
不过,在您添加该代码之前,有几点需要考虑。
首先,并非每个浏览器都支持 Service Worker。对于不自动更新的旧版本浏览器尤其如此。因此,最佳实践是在检查是否支持 navigator.serviceWorker
后,有条件地调用 navigator.serviceWorker.register()
。
其次,当您注册 Service Worker 时,浏览器会运行您的 service-worker.js
文件中的代码,并可能开始下载 URL 以填充缓存,具体取决于您的 Service Worker 的 install
和 activate
事件处理程序中的代码。
运行额外的代码和下载资源可能会占用宝贵的资源,而您的浏览器本可以使用这些资源来显示当前的网页。为了帮助避免这种干扰,最佳实践是延迟注册 Service Worker,直到浏览器完成渲染当前页面。近似实现此目的的一种便捷方法是等待 window.load
事件被触发。
将这两点结合起来,将此通用 Service Worker 注册代码添加到您的 register-sw.js
文件中
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js');
});
}
添加一些 Service Worker 日志记录代码
您的 service-worker.js
文件通常是 Service Worker 实现的所有逻辑所在的位置。您可以使用 Service Worker 生命周期事件、Cache Storage API 以及关于您的 Web 应用程序网络流量的知识,来创建一个完美制作的 Service Worker,随时准备处理您的 Web 应用程序的所有请求。
但是……这些都是以后学习的内容。在此阶段,重点是观察各种 Service Worker 事件,并熟练使用 Chrome 的 DevTools 来调试 Service Worker 的状态。
为此,请将以下代码添加到 service-worker.js
中,它将在 DevTools 控制台中记录消息以响应各种事件(但不会做太多其他事情)
self.addEventListener('install', (event) => {
console.log('Inside the install handler:', event);
});
self.addEventListener('activate', (event) => {
console.log('Inside the activate handler:', event);
});
self.addEventListener(fetch, (event) => {
console.log('Inside the fetch handler:', event);
});
熟悉 DevTools 中的 Service Workers 面板
现在您已经将代码添加到 register-sw.js
和 service-worker.js
文件中,现在可以访问示例项目的在线版本,并观察 Service Worker 的运行情况。
- 要预览网站,请按查看应用。然后按全屏
。
- 按 `Control+Shift+J`(在 Mac 上按 `Command+Option+J`)打开 DevTools。
- 点击 Console 选项卡。
您应该看到类似以下日志消息,表明 Service Worker 已安装并激活
然后访问 Applications 选项卡,并选择 Service Workers 面板。您应该看到类似以下内容
这让您知道有一个源 URL 为 service-worker.js
的 Service Worker,用于 Web 应用程序 solar-donkey.glitch.me
,当前已激活并正在运行。它还告诉您,目前有一个客户端(打开的标签页)正在被 Service Worker 控制。
您可以使用此面板上的链接,例如 Unregister
或 stop
,来更改当前注册的 Service Worker 以进行调试。
触发 Service Worker 更新流程
使用 Service Worker 进行开发时,要理解的关键概念之一是更新流程的概念。
在您的用户访问注册了 Service Worker 的 Web 应用程序后,他们最终将在其本地浏览器上安装当前 service-worker.js
副本的代码。但是,当您更新存储在 Web 服务器上的 service-worker.js 版本时会发生什么?
当回访用户返回到 Service Worker 范围内的 URL 时,浏览器将自动请求最新的 service-worker.js
并检查是否有任何更改。如果 Service Worker 脚本中的任何内容不同,则新的 Service Worker 将有机会安装、激活并最终接管控制。
您可以通过返回项目的代码编辑器,并对代码进行任何更改来模拟此更新流程。一个快速的更改是将
self.addEventListener('install', (event) => {
console.log('Inside the install handler:', event);
});
替换为
self.addEventListener('install', (event) => {
console.log('Inside the UPDATED install handler:', event);
});
进行更改后,返回到示例应用程序的在线版本,并在 DevTools Application 选项卡仍然打开的情况下重新加载页面。您应该看到类似以下内容
这表明此时已安装了两个版本的 Service Worker。以前的版本(已激活)正在运行并控制着当前页面。更新版本的 Service Worker 列在正下方。它处于 waiting 状态
,并且将保持等待状态,直到关闭所有受旧 Service Worker 控制的打开标签页。
此默认行为确保,如果您的新 Service Worker 与旧 Service Worker 的行为存在根本差异(例如,fetch
处理程序使用与旧版本 Web 应用程序不兼容的资源进行响应),则它将在用户关闭您的 Web 应用程序的所有先前实例后才会生效。
总结
您现在应该对注册 Service Worker 并使用 Chrome 的 DevTools 观察 Service Worker 行为的过程感到舒适。
您现在处于有利的位置,可以开始实施缓存策略,以及所有有助于您的 Web 应用程序可靠且快速加载的优点。