如何用 fetch 事件实现网络优先或缓存优先的多种缓存策略

3次阅读

Service Worker 中 fetch 事件是资源加载控制核心,支持网络优先、缓存优先、缓存 + 网络并行及动态策略四种模式,需结合 URL、资源类型等条件精准分流。

如何用 fetch 事件实现网络优先或缓存优先的多种缓存策略

在 Service Worker 中,fetch 事件是控制资源加载逻辑的核心入口。通过监听它,你可以决定一个请求是走网络、读缓存,还是两者结合(如网络优先 fallback 到缓存,或缓存优先再更新)。关键在于拦截请求后,用 event.respondWith() 主动返回一个 Response 对象。

网络优先:先试网络,失败再用缓存

适合内容更新频繁、强一致性要求高的场景(如用户通知、实时数据)。核心思路是发起网络请求,用 catch 捕获失败,再尝试匹配缓存。

  • 调用 fetch(request) 发起网络请求
  • 成功时直接返回响应;失败时(如离线、超时、跨域拒绝)进入 catch
  • catch 中打开对应缓存,用 cache.match(request) 查找命中项
  • 若缓存存在,返回它;否则返回一个兜底响应(如 new Response('Offline', { status: 503})

缓存优先:先查缓存,未命中再发网络

适合静态资源或变动不大的内容(如 CSS、JS、图片),能显著降低延迟和服务器压力。注意:它不自动更新缓存,需配合其他策略(如后台静默更新)保持新鲜度。

  • 先打开缓存(如 caches.open('v1')),再 match(request)
  • 命中则直接返回缓存响应
  • 未命中则调用 fetch(request),并将返回的响应克隆一份写入缓存(cache.put(request, response.clone())),再返回原始响应
  • 建议对非 GET 请求或特殊 header 的请求跳过缓存逻辑(避免缓存 POST 或带认证的响应)

缓存 + 网络并行:立即返回缓存,后台更新后刷新页面

兼顾速度与新鲜度,常用于 SPA 的 HTML 页面或关键资源。用户看到的是旧内容,但新内容已在后台拉取并缓存,下次访问即生效;还可触发 UI 提示“有新版本”。

  • cache.match(request),若有则立即返回(event.respondWith(cachedResponse)
  • 同时发起 fetch(request),成功后将响应存入缓存(cache.put(request, response)
  • 可选:通过 clients.matchAll() 获取所有打开的页面,并用 postMessage 通知其刷新
  • 注意避免重复写缓存或竞态问题,可用 cache.addAll([……]) 替代单个 put 提升可靠性

按资源类型 /URL 动态选择策略

实际项目中很少全局统一策略。应根据请求 URL、method、header 或资源类型(HTML / JSON / image)分流处理。

  • 例如:以 /api/ 开头的请求用网络优先;.css.js 用缓存优先;根路径 / 用缓存 + 网络并行
  • 可用正则或 URL 构造器解析 request.url,或检查 request.destination(如 'script''image'
  • 对带查询参数的请求(如 ?t=123),注意缓存键是否包含参数——通常需规范化(如剔除跟踪类参数)再匹配
星耀云
版权声明:本站原创文章,由 星耀云 2026-03-26发表,共计1284字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources