使用 Workbox 预缓存

服务工作线程的一项功能是能够在服务工作线程安装时将文件保存到缓存中。这称为“预缓存”。 借助预缓存,您无需访问网络即可向浏览器提供缓存的文件。对您的网站即使在离线状态下也需要的重要资源(主要网页、样式、后备图片和基本脚本)使用预缓存。

您可以选择使用 Workbox 进行预缓存。您可以编写自己的代码,以在安装 Service Worker 时预缓存关键资源。使用 Workbox 的主要好处是它具备开箱即用的版本控制功能。与必须自行管理这些文件的版本控制和更新相比,使用 Workbox 更新预缓存资源的问题要少得多。

预缓存清单

预缓存由网址列表和每个网址的相关版本信息驱动。这些信息统称为预缓存清单。清单是预缓存中所有内容状态的“可靠来源”,适用于给定版本的 Web 应用。采用 Workbox 使用的格式的预缓存清单如下所示:

[{
  url: 'app.abcd1234.js'
}, {
  url: 'offline.svg',
  revision: '7836745f'
}, {
  url: 'index.html',
  revision: '518747aa'
}]

安装服务工件后,系统会在缓存存储区中为所列的三个网址分别创建三个缓存条目。第一个资源的网址中已包含版本信息(app 是实际文件名,.abcd1234 包含版本信息,位于文件扩展名 .js 之前)。Workbox 的构建工具可以检测到这一点,并排除修订字段。另外两个资源的网址中不包含任何版本信息,因此 Workbox 的构建工具会创建一个单独的 revision 字段,其中包含本地文件内容的哈希值。

提供预缓存的资源

将资源添加到缓存只是预缓存工作的一部分 - 资源缓存后,它们需要响应传出请求。这需要在您的 Service Worker 中添加一个 fetch 事件监听器,该监听器可以检查哪些网址已预缓存,并在过程中绕过网络可靠地返回这些缓存的响应。由于 Service Worker 检查缓存中的响应(并在网络之前使用响应),因此这称为缓存优先策略

高效更新

预缓存清单可准确表示预期的缓存状态;如果清单中的网址/修订版本组合发生变化,服务工件会知道之前缓存的条目已失效,需要更新。只需执行单个网络请求(由浏览器在 Service Worker 更新检查中自动发出),即可确定需要刷新哪些预缓存的网址。

预缓存资源的更新

随着时间的推移,您会发布 Web 应用的新版本,因此需要及时更新之前预缓存的网址、预缓存新资源,并删除过时条目。只要您每次重新构建网站时都继续生成完整的预缓存清单,该清单就会随时充当预缓存状态的“可信来源”。

如果存在包含新修订版本字段的现有网址,或者清单中添加或删除了任何网址,则表示 Service Worker 需要执行更新(作为 installactivate 事件处理脚本的一部分)。例如,如果您对网站进行了一些更改并进行了重新构建,则最新的预缓存清单可能发生了以下更改:

[{
  url: 'app.ffaa4455.js'
}, {
  url: 'offline.svg',
  revision: '7836745f'
}, {
  url: 'index.html',
  revision: '518747aa'
}]

每项更改都会告知您的 Service Worker 需要发出新请求来更新之前缓存的条目 ('offline.svg''index.html') 和缓存新网址 ('app.ffaa4455.js'),以及删除不再使用的网址 ('app.abcd1234.js')。

真正的“应用商店”安装体验

预缓存的另一个好处是,您可以为用户提供在“应用商店”安装之外难以实现的体验。用户首次访问您网站应用中的任何网页后,您或许可以预先缓存显示网站应用的任何视图所需的所有网址,而无需等到用户访问每个单独的视图。

用户安装应用时,希望所有部分都能快速显示,而不仅仅是他们之前访问过的视图。预缓存可为 Web 应用带来相同的体验。

您的哪些资产应预缓存?

请参阅确定正在加载的内容指南,详细了解哪些网址最适合预缓存。一般规则是,预缓存在早期加载且对显示给定网页的基本结构至关重要的所有 HTML、JavaScript 或 CSS。

最好避免预缓存稍后才会加载的媒体或其他资源(除非对您的 Web 应用的功能至关重要)。而是应使用运行时缓存策略,确保这些资源随用随缓存。

请始终记住,预缓存涉及使用用户设备上的网络带宽和存储空间(就像从应用商店安装应用一样)。作为开发者,您需要谨慎预缓存,避免预缓存清单过大。

Workbox 的构建工具可帮助您了解预缓存清单中的项数量以及预缓存载荷的总大小。

预缓存的前期费用可为您的 Web 应用的回访者带来长期利益,因为预缓存可避免快速访问网络,从而随着时间的推移节省带宽,这笔费用最终会得到回报。