改善 Service Worker 的开发体验

虽然 Service Worker 生命周期可确保安装和更新过程可预测,但这会使本地开发周期更加细微。

在典型的本地开发周期中,开发者在文本编辑器中保存对文件所做的更改,然后切换到浏览器来验证更改,此过程将重复。混合使用 Service Worker 时,此周期大致相同,但开发者的预期与浏览器的预期之间可能存在差异。

本地开发例外情况

一般情况下,Service Worker API 仅适用于通过 HTTPS 提供的页面,但也存在此规则的例外情况,即通过 HTTP 提供这些 API。一个值得注意的例外情况是,通过 localhost 提供的网页非常适合本地开发。

但是,开发者在 hosts 文件中指定除 localhost 之外的本地主机名的情况并不少见。在本地开发环境中,如果多个项目需要单独的主机名,则必须执行此操作。在这种情况下,只需配置自签名证书即可。

更方便的解决方法是指示浏览器对 Service Worker 测试设置例外。对于 Chrome,请前往 chrome://flags/#unsafely-treat-insecure-origin-as-secure,然后将不安全的源指定为安全源。Firefox 提供了一种通过 about:config 中的 devtools.serviceWorkers.testing.enabled 设置在不安全的源上测试 Service Worker 的方法。

Service Worker 开发辅助工具

在本地开发中同时使用 Service Worker 可能会导致看似意外的行为。例如,假设没有版本控制的静态资源只采用缓存策略,或者某个预缓存的“您处于离线状态”网页预计会在进行更改后重新加载。 由于这些资源的过时版本始终由 Cache 实例提供,因此它们似乎永远不会更新!令人沮丧的是,Service Worker 只是在执行其构建的任务,但有一些方法可以让您更轻松地进行测试。

到目前为止,测试 Service Worker 的最有效方法是依靠无痕浏览窗口,例如 Chrome 中的无痕式窗口或 Firefox 的无痕浏览功能。每次打开无痕浏览窗口时,您都会重新开始。 没有处于活跃状态的 Service Worker,也没有打开的 Cache 实例。此类测试的程序如下:

  1. 打开无痕浏览窗口。
  2. 导航到注册 Service Worker 的页面。
  3. 验证 Service Worker 的行为是否符合预期。
  4. 关闭无痕式窗口。
  5. 重复。

通过此过程,您可以真实地模拟 Service Worker 生命周期。

Chrome DevTools 的 Application 面板中提供的其他测试工具可以提供帮助,但它们可以通过某些方式修改 Service Worker 的生命周期。

Chrome DevTools Application 面板。

应用面板包含一个名为 Service Workers 的子面板,显示当前页面的活动 Service Worker。每个活跃的 Service Worker 可以手动更新,甚至可以完全取消注册。顶部还有三个切换开关,可以帮助您进行开发。

  1. 离线功能会模拟离线条件。这有助于测试处于活动状态的 Service Worker 是否正在提供离线内容。
  2. Update on load(重新加载时更新):启用后,每次页面重新加载时都会重新获取并替换当前的 Service Worker。
  3. Bypass for network:切换为开启状态时,会规避 Service Worker 的 fetch 事件中的任何代码,并始终从网络获取内容。

这些切换开关非常实用,尤其是绕过网络,这在您开发具有活跃 Service Worker 的项目时非常有用,但同时希望确保体验在没有 Service Worker 的情况下也能正常运行。

Firefox 在其开发者工具中有类似的应用面板,但功能仅限于显示已安装的 Service Worker,以及手动取消注册当前页面的任何活跃 Service Worker。这种方法同样有帮助,但需要在本地开发周期中完成更多的手动工作。

Shift 键并重新加载

如果使用活跃的 Service Worker 进行本地开发,而不需要刷新时更新绕过网络提供的功能,那么按住 Shift 并按刷新按钮,也会很有帮助。

这种做法称为“强制刷新”,会绕过网络的 HTTP 缓存。 当 Service Worker 处于活动状态时,强制刷新也将完全绕过 Service Worker。

如果不确定特定的缓存策略是否按预期工作,此功能非常有用;从网络中获取所有内容以比较使用 Service Worker 和不使用 Service Worker 的行为会非常有用。更好的是,它是一种指定行为,因此所有支持 Service Worker 的浏览器都会观察它。

检查缓存内容

如果无法检查缓存,则很难判断缓存策略是否按预期运行。 当然,可以在代码中检查缓存,但当使用可视化工具执行该任务时,该过程会涉及调试程序和/或 console 语句。 Chrome DevTools 中的 Application 面板提供了一个子面板,用于检查 Cache 实例的内容。

在开发者工具中检查缓存

此子面板提供如下功能,简化了 Service Worker 的开发工作:

  • 查看 Cache 实例的名称。
  • 能够检查已缓存资源的响应正文及其关联的响应标头。
  • 从缓存中逐出一项或多项内容,甚至删除整个 Cache 实例。

此图形界面可让您更轻松地检查 Service Worker 缓存,从而了解 Service Worker 缓存中是否已添加、更新或完全移除了项目。Firefox 提供了具有类似功能的缓存查看器,不过它位于单独的存储面板中。

模拟存储配额

在拥有大量大型静态资源(例如高分辨率图片)的网站中,可能会达到存储空间配额。在这种情况下,浏览器会从缓存中逐出它认为已过时或值得牺牲的项,以便为新的资源腾出空间。

处理存储空间配额应该是 Service Worker 开发过程的一部分,而 Workbox 使该过程比自行管理该过程更简单。但无论是否使用 Workbox,最好通过模拟自定义存储空间配额来测试缓存管理逻辑。

存储空间使用情况查看器。
Chrome 开发者工具的 Application 面板中的存储空间使用情况查看器。此处正在设置自定义存储空间配额。

Chrome 开发者工具中的“Application”面板有一个存储子面板,该子面板提供有关页面当前使用了多少存储空间配额的信息。它还允许以兆字节为单位指定自定义配额。 这一规则生效后,Chrome 会强制执行自定义存储空间配额,以便对其进行测试。

顺便说一下,该子面板还包含一个清除网站数据按钮,以及一系列相关的复选框,用于指明在点击该按钮时应清除哪些内容。 其中包括所有打开的 Cache 实例,以及取消注册任何控制该页面的有效 Service Worker。

更简单的开发,更高的工作效率

当开发者不受阻碍时,他们便可以更有信心地工作,工作效率也会更高。 使用 Service Worker 进行本地开发可能会略有不同,但并不必费时费力。利用这些提示和技巧,使用活跃的 Service Worker 进行开发应该会更加透明和可预测,从而带来更好的开发者体验。