使用 Service Worker

此 Codelab 将介绍如何在您的 Web 中注册 Service Worker 应用,并使用 Chrome 开发者工具观察其行为。它还 介绍了一些调试技巧,这些技巧在处理代码时可能会派上用场 Service Worker。

熟悉示例项目

示例项目中与此 Codelab 最相关的文件如下:

  • register-sw.js 最初为空,但将包含用于注册服务工作线程的代码。它已通过 <script> 加载 index.html 内。
  • service-worker.js 同样为空。该文件包含 此项目的 Service Worker。

添加 Service Worker 注册代码

Service Worker(即使是空的 Service Worker,例如当前的 service-worker.js 文件) 除非是 已注册 。您可以通过调用以下方法来实现此目的:

navigator.serviceWorker.register(
  '/service-worker.js'
)

放在 register-sw.js 文件中。

不过,在添加该代码之前,需要注意以下几点 。

首先,并不是所有浏览器 支持 Service Worker。尤其是旧版浏览器, 不会自动更新。因此,最佳做法是 在检查是否满足条件后,navigator.serviceWorker.register() 支持 navigator.serviceWorker

其次,当您注册 Service Worker 时,浏览器会运行您的 service-worker.js 文件,并可能会开始下载要填充的网址 具体取决于 Service Worker 的 installactivate 事件处理脚本

运行其他代码和下载资源可能会占用 宝贵的资源,您的浏览器可以用来显示当前的 网页中。为避免此类干扰,最好延迟注册服务工作器,直到浏览器完成当前网页的呈现。若要近似地实现此操作,一种方便的方法是等待 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 应用请求。

不过…这些内容留待以后再学习。在此阶段,重点是观察各种服务工作线程事件,并熟练使用 Chrome 的 DevTools 调试服务工作线程的状态。

为此,请将以下代码添加到 service-worker.js,这将记录 向开发者工具控制台发送错误消息,以响应各种事件(但并不能 else):

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.jsservice-worker.js。 现在即可访问示例项目的 Live 版本,并观察 Service Worker。

  • 如需预览网站,请按查看应用。然后按 全屏 全屏
  • 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
  • 点击控制台标签页。

您应该会看到类似如下的日志消息: 显示 Service Worker 已安装并激活:

显示 Service Worker 已安装并激活。

然后,访问 Applications 标签,并选择 Service Workers 面板。 您应看到类似下图的内容:

在 Service Worker 面板中显示 Service Worker 详细信息。

这样您就可以知道存在一个源网址为 service-worker.js,对于 Web 应用 solar-donkey.glitch.me,当前为 处于激活状态且正在运行。它还会告知您当前有 1 个客户端(打开的标签页)由该服务工作器控制。

您可以使用此面板上的链接(例如 Unregisterstop) 更改当前注册的 Service Worker,以用于调试。

触发 Service Worker 更新流程

使用 Service Worker 进行开发时,需要理解的一个关键概念是 其理念 更新流程

在您的用户访问注册 Service Worker 的 Web 应用后,他们将结束 提供当前安装的 service-worker.js 副本的代码 本地浏览器但是,如果你更新 存储在网络服务器上的 service-worker.js?

当重复访问者返回到 Service Worker 范围内的某个网址时, 浏览器会自动请求最新的 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);
});

完成更改后,返回示例应用的 Live 版本,并且 重新加载页面,让开发者工具的“Application”标签页仍然打开。您应该会看到 如下所示:

显示已安装的两个 Service Worker 版本。

这表明此集群中安装了两个版本的 Service Worker 。之前的版本(已经激活)正在运行, 当前网页的控件。更新的 Service Worker 版本将列出 。它位于 waiting 状态、 并会一直等待,直到所有打开的标签页都由 关闭旧 Service Worker。

此默认行为可确保,如果您的新服务工件与旧服务工件的行为存在根本差异(例如,fetch 处理脚本使用与旧版 Web 应用不兼容的资源进行响应),则在用户关闭 Web 应用的所有之前实例之前,新服务工件不会生效。

总结

现在,您应该已经熟悉 Service Worker 的注册流程了 以及使用 Chrome 的 DevTools 观察 Service Worker 的行为。

现在,您已经做好了开始实现缓存策略以及所有有助于 Web 应用可靠快速加载的其他实用功能的准备。