Angular service worker介绍

1. 前言

Service Worker 增强了传统的 Web 部署模型,并使应用程序能够提供与 Native application 相当的可靠性,性能和用户体验。将服务工作进程添加到 Angular 应用程序是将应用程序转换为渐进式 Web 应用程序(也称为 PWA)的步骤之一。

简单来说,Service worker 是在 Web 浏览器中运行并管理应用程序缓存的脚本。

Service worker 充当网络代理。它们拦截应用程序发出的所有 HTTP 请求,并可以选择如何响应这些请求。例如,他们可以查询本地缓存并提供缓存的响应(如果有)。代理不仅限于通过编程 API 发出的请求,例如 fetch;它还包括 HTML 中引用的资源,甚至是对 index.html 的初始请求。因此,基于 Service worker 的缓存是完全可编程的,不依赖于服务器指定的缓存标头。

与组成应用程序的其他脚本(如 Angular application bundle)不同,服务工作进程在用户关闭选项卡后仍然保留。下次浏览器加载应用程序时,Service worker 首先加载,并且可以截获每个资源请求以加载应用程序。如果服务工作进程被设计为这样做,它可以完全满足应用程序的加载,而无需网络。

即使在快速可靠的网络中,往返延迟也会在加载应用程序时引入明显的延迟。使用服务工作进程来减少对网络的依赖可以显著改善用户体验。

2. Angular Service worker

Angular 应用程序作为单页应用程序,也是 Service worker 的这项技术的主要受益者。从版本 5.0.0 开始,Angular 附带了一个 Service worker 实现。Angular 开发人员可以利用此 Service worker,并从它提供的更高的可靠性和性能中受益,而无需针对低级 API 进行编码。

Angular Service worker 旨在优化应用程序在慢速或不可靠网络条件下的最终用户体验,同时最大限度地降低由于缓存导致的过时内容的风险。

为了实现这一点,Angular 服务工作者遵循以下准则:

  • 缓存应用程序类似于本地安装的应用程序。应用程序作为一个整体进行缓存,所有文件一起更新。

  • 正在运行的应用程序将继续使用所有文件的相同版本运行。它不会突然开始从较新版本接收缓存文件,避免可能的不兼容性。

  • 当用户刷新应用程序时,他们会看到完整的最新的版本。

  • 更新在后台进行。在安装并准备好更新之前,将提供应用程序的先前版本。

  • Service worker 尽可能节省带宽。仅当资源发生更改时,才会下载资源。

为了支持这些行为,Angular Service worker 从服务器加载一个清单文件。该文件名为 ngsw.json(不要与 web 应用程序清单混淆),描述了要缓存的资源,并包括每个文件内容的哈希。当部署应用程序的更新时,清单的内容会发生变化,通知服务工作者应该下载并缓存应用程序的新版本。此清单是从 CLI 生成的名为 ngsw-config.json 的配置文件生成的。
安装 Angular Service worker 非常简单。除了在浏览器中注册 Angular Service worker 外,还可以注入一些额外的服务,这些服务可与 Service worker 进行交互并控制 Service worker。例如,应用程序可以要求在新的更新可用时得到通知,或者应用程序可以请求服务工作程序检查服务器是否有可用的更新。

3. 使用 Service worker 的前提条件

要利用 Angular 服务工作者的所有功能,请使用最新版本的 Angular 和 Angular CLI。

对于要注册的 Service worker,必须通过 HTTPS 而不是 HTTP 访问应用程序。浏览器会忽略通过不安全连接提供服务的页面上的服务工作进程。原因是 Service worker 非常强大,因此需要格外小心以确保服务工作进程脚本未被篡改。

此规则有一个例外:为了使本地开发更加简单,浏览器在访问 localhost 上的应用程序时不需要安全连接。

4. 关于浏览器支持

要使用 Angular Service worker,您的应用程序必须在支持 Service worker 的 Web 浏览器中运行。目前,Service worker 在最新版本的 Chrome、Firefox、Edge、Safari、Opera、UC 浏览器(Android 版本)和 Samsung Internet 中得到支持。像 IE 和 Opera Mini 这样的浏览器不支持 Service worker。

如果用户使用不支持 Service worker 的浏览器访问您的应用程序,则不会注册服 Service worker,也不会发生离线缓存管理和推送通知等相关行为。具体来说:

  • 浏览器不会下载服务工作者脚本和 ngsw.json 配置文件。
  • 与 Service worker 进行交互的主动尝试(例如调用 SwUpdate.checkForUpdate())会返回拒绝的 Promise。
  • 相关服务的 observable 事件(例如 SwUpdate.available)不会被触发。

强烈建议您确保应用程序即使在浏览器不支持 Service worker 的情况下也能正常工作。尽管不支持 Service worker 缓存,但如果应用程序尝试与 Service worker 交互,它仍会报告错误。例如,调用 SwUpdate.checkForUpdate() 会返回拒绝的 Promise。为避免此类错误,请使用 SwUpdate.isEnabled 检查是否启用了 Angular Service worker。

要了解其他支持 Service worker 的浏览器,请参阅 Can I UseMDN 文档

5. 相关资源

本节的其余文章专门介绍了 Service worker 的 Angular 实现。

App Shell
Service Worker Communication
Service Worker Notifications
Service Worker in Production
Service Worker Configuration

有关 Service Worker 的详细信息,请参阅Service Workers: an Introduction

有关浏览器支持的详细信息,请参阅 Service Workers:an Introduction的浏览器支持部分、Jake Archibald 的 Service worker 准备好了吗?Can I use

有关其他建议和示例,请参阅:

使用 Angular Service Worker 进行预缓存
使用 Angular CLI 创建 PWA

6. Angular 系列文章

最新更新以及更多 Angular 相关文章请访问 Angular 合集 | 鹏叔的技术博客

7. 参考文档

Angular service worker introduction