Service worker 缓存和 HTTP 缓存

在 service worker 缓存和 HTTP 缓存层中使用一致或不同的过期逻辑的优缺点。

虽然 service worker 和 PWA 正在成为现代 web 应用程序的标准,但资源缓存已变得比以往任何时候都更加复杂。本文涵盖了浏览器缓存的概况,包括:

  • service worker 缓存和 HTTP 缓存的用例和区别。
  • 与常规 HTTP 缓存策略相比,不同 service worker 缓存过期策略的优缺点。

缓存流程概述

在较高层面上,浏览器在请求资源时遵循以下缓存顺序:

  1. Service worker 缓存:Service worker 检查资源是否在其缓存中,并根据其编程的缓存策略决定是否返回资源本身。请注意,这不会自动发生。您需要在您的 service worker 中创建一个 fetch 事件处理程序并拦截网络请求,以便请求从 service worker 的缓存而不是网络提供服务。
  2. HTTP 缓存(也称为浏览器缓存):如果在 HTTP 缓存中找到资源且尚未过期,则浏览器会自动使用 HTTP 缓存中的资源。
  3. 服务器端: 如果在 service worker 缓存或 HTTP 缓存中找不到任何内容,则浏览器将转到网络以请求资源。如果资源未缓存在 CDN 中,则请求必须一直返回到源服务器。

Caching flow

缓存层

Service worker 缓存

Service worker 拦截网络类型的 HTTP 请求,并使用 缓存策略 来确定应将哪些资源返回给浏览器。Service worker 缓存和 HTTP 缓存具有相同的总体目的,但 service worker 缓存提供更多的缓存功能,例如对缓存内容以及缓存方式进行精细控制。

控制 Service worker 缓存

Service worker 使用 事件侦听器(通常是 fetch 事件)拦截 HTTP 请求。此 代码片段 演示了 Cache-First 缓存策略的逻辑。

A diagram showing how service workers intercept HTTP requests

强烈建议使用 Workbox 以避免重复造轮子。例如,您可以使用 单行正则表达式代码注册资源 URL 路径

import {registerRoute} from 'workbox-routing';

registerRoute(new RegExp('styles/.*\\.css'), callbackHandler);

Service worker 缓存策略和用例

下表概述了常见的 service worker 缓存策略以及每种策略的适用场景。

策略 新鲜度原理 用例
仅网络 内容必须始终是最新的。
  • 支付和结账
  • 余额报表
网络回退到缓存 最好提供最新内容。但是,如果网络失败或不稳定,则可以接受提供稍微旧的内容。
  • 及时数据
  • 价格和费率(需要免责声明)
  • 订单状态
陈旧内容再验证 可以立即提供缓存内容,但将来应使用更新的缓存内容。
  • 新闻提要
  • 产品列表页面
  • 消息
缓存优先,回退到网络 内容是非关键性的,可以从缓存中提供以提高性能,但 service worker 应偶尔检查更新。
  • 应用 shell
  • 常用资源
仅缓存 内容很少更改。
  • 静态内容

Service worker 缓存的其他好处

除了对缓存逻辑进行精细控制外,service worker 缓存还提供:

  • 为您的来源提供更多内存和存储空间: 浏览器在每个 来源 的基础上分配 HTTP 缓存资源。换句话说,如果您有多个子域名,它们都共享同一个 HTTP 缓存。无法保证您的来源/域的内容会在 HTTP 缓存中长期保留。例如,用户可以通过手动从浏览器的设置 UI 中清除缓存,或者在页面上触发硬重新加载来清除缓存。使用 service worker 缓存,您可以更大概率地使您的缓存内容保持缓存状态。请参阅 持久存储 以了解更多信息。
  • 在网络不稳定或离线体验方面具有更高的灵活性: 使用 HTTP 缓存,您只有二元选择:资源是否缓存。使用 service worker 缓存,您可以更轻松地缓解小的“中断”(使用“陈旧内容再验证”策略),提供完整的离线体验(使用“仅缓存”策略),甚至介于两者之间的某种体验,例如使用来自 service worker 缓存的页面部分和排除某些部分(使用“设置捕获处理程序”策略)的自定义 UI(在适当的情况下)。

HTTP 缓存

浏览器首次加载网页和相关资源时,它会将这些资源存储在其 HTTP 缓存中。HTTP 缓存通常由浏览器自动启用,除非最终用户已显式禁用它。

使用 HTTP 缓存意味着依赖服务器来确定何时缓存资源以及缓存多长时间。

使用 HTTP 响应标头控制 HTTP 缓存过期

当服务器响应浏览器对资源的请求时,服务器使用 HTTP 响应标头告知浏览器应缓存资源多长时间。请参阅 响应标头:配置您的 web 服务器 以了解更多信息。

HTTP 缓存策略和用例

HTTP 缓存比 service worker 缓存简单得多,因为 HTTP 缓存仅处理基于时间 (TTL) 的资源过期逻辑。请参阅 您应该使用哪些响应标头值?摘要 以了解有关 HTTP 缓存策略的更多信息。

设计您的缓存过期逻辑

本节解释了在 service worker 缓存和 HTTP 缓存层中使用一致过期逻辑的优缺点,以及在这些层中使用单独过期逻辑的优缺点。

下面的 Glitch 演示了 service worker 缓存和 HTTP 缓存在不同场景中的工作方式

所有缓存层的一致过期逻辑

为了演示优缺点,我们将查看 3 种场景:长期、中期和短期。

场景 长期缓存 中期缓存 短期缓存
Service worker 缓存策略 缓存,回退到网络 陈旧内容再验证 网络回退到缓存
Service worker 缓存 TTL 30 天 1 天 10 分钟
HTTP 缓存 max-age 30 天 1 天 10 分钟

场景:长期缓存(缓存,回退到网络)

  • 当缓存资源有效(<= 30 天)时:Service worker 立即返回缓存的资源,而无需访问网络。
  • 当缓存资源过期(> 30 天)时:Service worker 访问网络以获取资源。浏览器在其 HTTP 缓存中没有资源的副本,因此它会访问服务器端以获取资源。

缺点:在这种情况下,HTTP 缓存提供的价值较小,因为当 service worker 中的缓存过期时,浏览器始终会将请求传递到服务器端。

场景:中期缓存(陈旧内容再验证)

  • 当缓存资源有效(<= 1 天)时:Service worker 立即返回缓存的资源,并访问网络以获取资源。浏览器在其 HTTP 缓存中具有资源的副本,因此它会将该副本返回给 service worker。
  • 当缓存资源过期(> 1 天)时:Service worker 立即返回缓存的资源,并访问网络以获取资源。浏览器在其 HTTP 缓存中没有资源的副本,因此它会访问服务器端以获取资源。

缺点:service worker 需要额外的缓存清除来覆盖 HTTP 缓存,以便充分利用“再验证”步骤。

场景:短期缓存(网络回退到缓存)

  • 当缓存资源有效(<= 10 分钟)时:Service worker 访问网络以获取资源。浏览器在其 HTTP 缓存中具有资源的副本,因此它会将该副本返回给 service worker,而无需访问服务器端。
  • 当缓存资源过期(> 10 分钟)时:Service worker 立即返回缓存的资源,并访问网络以获取资源。浏览器在其 HTTP 缓存中没有资源的副本,因此它会访问服务器端以获取资源。

缺点:与中期缓存场景类似,service worker 需要额外的缓存清除逻辑来覆盖 HTTP 缓存,以便从服务器端获取最新资源。

所有场景中的 Service worker

在所有场景中,当网络不稳定时,service worker 缓存仍然可以返回缓存的资源。另一方面,当网络不稳定或断开时,HTTP 缓存不可靠。

Service worker 缓存和 HTTP 层中不同的缓存过期逻辑

为了演示优缺点,我们将再次查看长期、中期和短期场景。

场景 长期缓存 中期缓存 短期缓存
Service worker 缓存策略 缓存,回退到网络 陈旧内容再验证 网络回退到缓存
Service worker 缓存 TTL 90 天 30 天 1 天
HTTP 缓存 max-age 30 天 1 天 10 分钟

场景:长期缓存(缓存,回退到网络)

  • 当缓存资源在 service worker 缓存中有效(<= 90 天)时:Service worker 立即返回缓存的资源。
  • 当缓存资源在 service worker 缓存中过期(> 90 天)时:Service worker 访问网络以获取资源。浏览器在其 HTTP 缓存中没有资源的副本,因此它会访问服务器端。

优点和缺点

  • 优点:用户体验到即时响应,因为 service worker 立即返回缓存的资源。
  • 优点:Service worker 可以更精细地控制何时使用其缓存以及何时请求资源的新版本。
  • 缺点:需要定义明确的 service worker 缓存策略。

场景:中期缓存(陈旧内容再验证)

  • 当缓存资源在 service worker 缓存中有效(<= 30 天)时:Service worker 立即返回缓存的资源。
  • 当缓存资源在 service worker 缓存中过期(> 30 天)时:Service worker 访问网络以获取资源。浏览器在其 HTTP 缓存中没有资源的副本,因此它会访问服务器端。

优点和缺点

  • 优点:用户体验到即时响应,因为 service worker 立即返回缓存的资源。
  • 优点:Service worker 可以确保下一次 对给定 URL 的请求使用来自网络的最新响应,这要归功于在“后台”发生的再验证。
  • 缺点:需要定义明确的 service worker 缓存策略。

场景:短期缓存(网络回退到缓存)

  • 当缓存资源在 service worker 缓存中有效(<= 1 天)时:Service worker 访问网络以获取资源。如果 HTTP 缓存中存在资源,则浏览器从 HTTP 缓存返回资源。如果网络中断,则 service worker 从 service worker 缓存返回资源
  • 当缓存资源在 service worker 缓存中过期(> 1 天)时:Service worker 访问网络以获取资源。浏览器通过网络获取资源,因为其 HTTP 缓存中的缓存版本已过期。

优点和缺点

  • 优点:当网络不稳定或中断时,service worker 立即返回缓存的资源。
  • 缺点:service worker 需要额外的缓存清除来覆盖 HTTP 缓存并发出“网络优先”请求。

结论

鉴于缓存场景组合的复杂性,不可能设计一个规则来涵盖所有情况。但是,根据前面部分的发现,在设计缓存策略时,可以考虑以下几点建议:

  • Service worker 缓存逻辑不需要与 HTTP 缓存过期逻辑一致。如果可能,请在 service worker 中使用更长的过期逻辑,以便为 service worker 提供更多控制权。
  • HTTP 缓存仍然发挥着重要作用,但当网络不稳定或断开时,它不可靠。
  • 重新审视每个资源的缓存策略,以确保您的 service worker 缓存策略能够发挥其价值,而不会与 HTTP 缓存冲突。

了解更多