使用 Workbox 进行运行时缓存

运行时缓存是指“随时”将响应逐步添加到缓存中。虽然运行时缓存对当前请求的可靠性没有帮助,但可以提高将来对同一网址发出的请求的可靠性。

浏览器的 HTTP 缓存就是一个运行时缓存示例;它仅在请求指定网址之后才会填充。但是,借助 Service Worker,您可以实现运行时缓存,超出了 HTTP 缓存本身所能提供的功能。

制定策略

预缓存(始终尝试从缓存中提供一组预定义文件)相反,运行时缓存可以通过多种方式合并网络和缓存访问权限。每种组合通常称为缓存策略。关键缓存策略包括:

  • 网络优先
  • 缓存优先
  • 重新验证时过时

网络优先

在此方法中,您的 Service Worker 会先尝试从网络中检索响应。如果网络请求成功,那就太好了!系统会将响应返回到您的 Web 应用,并使用 Cache Storage API 存储响应的副本,即创建新条目或更新同一网址的旧条目。

显示从页面到 Service Worker 以及从 Service Worker 流向网络的请求。网络请求失败,因此请求会进入缓存。

如果网络请求完全失败,或返回响应所花的时间过长,则会返回缓存中的最新响应。

缓存优先

缓存优先策略实际上与网络优先策略相反。在此方法中,当 Service Worker 拦截请求时,它会先使用 Cache Storage API 查看是否有可用的缓存响应。如果存在,系统会将该响应返回给 Web 应用。

但如果缓存未命中,则 Service Worker 会前往网络并尝试从那里检索响应。假设网络请求成功,它会返回到您的 Web 应用,并在缓存中保存一份副本。该缓存副本将用于在下次针对相同网址发出请求时绕过网络。

显示从页面到 Service Worker 以及从 Service Worker 发送至缓存的请求。缓存请求失败,因此请求会进入网络。

重新验证时过时

Stale-while-revalidate 是一种混合模式。使用它时,您的 Service Worker 将立即检查缓存的响应,如果找到缓存响应,则将其传回您的 Web 应用。

在此期间,无论是否存在缓存匹配,您的 Service Worker 都会触发网络请求来获得“最新”响应。此响应用于更新之前缓存的任何响应。如果初始缓存检查未成功,网络响应的副本也会传回您的 Web 应用。

显示从页面到 Service Worker 以及从 Service Worker 发送至缓存的请求。缓存会立即返回一个响应,同时还会从网络中获取更新以用于将来的请求。

为什么应使用 Workbox?

您通常需要在自己的 Service Worker 中反复重写这些缓存策略。Workbox 并非采用这种做法,而是将其打包为策略库的一部分,供您随时使用。

Workbox 还提供版本控制支持,让您能够自动过期缓存的条目,或者在先前缓存的条目更新时通知 Web 应用。

您的哪些素材资源应缓存?采用何种策略?

可以将运行时缓存视为对预缓存的补充。如果您的所有资源都已预先缓存,那么就大功告成了,在运行时不需要缓存任何内容。不过,对于任何相对复杂的 Web 应用,您很可能无法预缓存所有内容。

较大的媒体文件、从第三方主机(如 CDN)提供的资源(或 API 响应)只是无法有效预缓存的资源类型的几个示例。使用开发者工具中的“Network”面板可以确定属于此类别的请求,并针对每种请求考虑新鲜度与可靠性之间的权衡取舍。

使用 stale-while-revalidate 系统,优先考虑可靠性而非新鲜度

由于 stale-while-revalidate 策略几乎会立即返回缓存的响应(在通过第一个请求填充缓存后),您最终将获得可靠的快速性能。这就涉及到如何获得可能过时的响应数据(与从网络中检索到的响应数据相比)。当您知道立即显示某些内容是关键所在(即使该值为旧值)时,对用户个人资料图片等资源或用于填充视图的初始 API 响应等资源最有效。

使用网络优先,优先考虑新鲜度而非可靠性

从某种意义上讲,使用网络优先的策略相当于在与网络的竞争中取得失败,它被赋予了优先权,但这也给可靠性带来了不确定性。对于某些类型的资源,获得最新的响应比获取过时的信息更可取。例如,在针对频繁更新的报道文本发出 API 请求时,您可能更希望获得新鲜度。

通过在 Service Worker 内使用网络优先策略,而不仅仅是直接对照网络,您可以回退到某个内容,即使它是可能过时的响应。虽然速度不快,但至少在离线状态下仍会保持可靠性。

为版本化网址使用缓存优先

在缓存优先策略中,条目一旦缓存,就不再更新。因此,请确保仅针对您确定不太可能会更改的素材资源使用该选项。特别是,它最适合包含版本控制信息的网址 - 同类型的网址还应使用 Cache-Control: max-age=31536000 响应标头提供。