Service Worker 缓存和 HTTP 缓存
在 Service Worker 缓存和 HTTP 缓存层中使用一致或不同的过期逻辑的优缺点。
虽然 Service Worker 和 PWA 正在成为现代 Web 应用程序的标准,但资源缓存变得比以往任何时候都复杂。本文涵盖了浏览器缓存的重点内容,具体包括:
- Service Worker 缓存与 HTTP 缓存的用例和区别。
- 与常规 HTTP 缓存策略相比,不同 Service Worker 缓存过期策略的优缺点。
缓存流程概述 #
概括地说,浏览器在请求资源时会遵循以下缓存顺序:
- Service Worker 缓存:Service Worker 检查资源是否在其缓存中,并根据其编程的缓存策略决定是否返回资源本身。请注意,这个操作不会自动发生。您需要在 Service Worker 中创建一个 fetch 事件处理程序并拦截网络请求,这样才能从 Service Worker 的缓存而不是网络支持这些请求。
- HTTP 缓存(也称为浏览器缓存):如果资源位于 HTTP 缓存中且尚未过期,则浏览器会自动使用 HTTP 缓存中的资源。
- **服务器端:**如果在 Service Worker 缓存或 HTTP 缓存中未找到任何内容,则浏览器将向网络请求资源。如果资源未在 CDN 中缓存,则请求必须返回到源服务器。

缓存层 #
Service Worker 缓存 #
Service Worker 拦截网络类型的 HTTP 请求并使用缓存策略来确定应将哪些资源返回给浏览器。 Service Worker 缓存和 HTTP 缓存的通用目的相同,但 Service Worker 缓存提供了更多的缓存功能,例如,对缓存内容和缓存完成方式进行精细控制。
控制 Service Worker 缓存 #
Service Worker 使用事件侦听器(通常是 fetch
事件)拦截 HTTP 请求。以下代码片段演示了缓存优先这一缓存策略的逻辑。

强烈建议使用工具箱以免白费力气重复工作。例如,您可以使用一行正则表达式代码来注册资源 URL 路径。
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('styles/.*\\.css'), callbackHandler);
Service Worker 缓存策略和用例 #
下表概述了常见的 Service Worker 缓存策略以及每种策略的适用场合。
策略 | 新鲜度理论 | 用例 |
---|---|---|
内容必须始终保持最新。 |
| |
最好提供新内容。但是,如果网络出现故障或不稳定,也可以提供稍旧的内容。 |
| |
可以立即提供缓存内容,但将来应该使用更新的缓存内容。 |
| |
内容不重要,并且可以从缓存中获得以提高性能,但 Service Worker 应该偶尔检查是否有更新。 |
| |
内容很少改变。 |
|
Service Worker 缓存的其他优势 #
除了对缓存逻辑的精细控制外,Service Worker 缓存还具有以下优势:
- **为您的源提供更多内存和存储空间:**浏览器基于每个源分配 HTTP 缓存资源。换句话说,如果您有多个子域,它们将共享相同的 HTTP 缓存。无法保证您的源/域的内容会长时间保留在 HTTP 缓存中。例如,用户可以通过以下方式清除缓存:在浏览器的设置 UI 中进行手动清理或者触发页面上的硬重新加载。使用 Service Worker 缓存,您的缓存内容保持缓存状态的可能性要高得多。请参阅持久存储以了解更多信息。
- **网络不稳定或离线时提高灵活性:**使用 HTTP 缓存,您只能做二元选择:要么缓存资源,要么不缓存。使用 Service Worker 缓存,您可以更轻松地缓解小“小问题”(使用“重新验证时过期”策略)、提供完整的离线体验(使用“仅缓存”策略),或者是介于二者之间,例如,对于自定义 UI,必要时,页面的一部分来自 Service Worker 缓存,而某些部分被排除在外(使用“设置捕获处理程序“策略)。
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 缓存最长时限 | 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 缓存最长时限 | 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 缓存发生冲突。