← 返回题目列表

Service Worker 如何提升前端加载性能?缓存策略怎么选?

中等 第 26 / 29 题 更新于 2026/07/29
前端性能Service Worker缓存策略PWA

简化版

Service Worker 可以拦截同源请求,把静态资源或接口响应缓存到 Cache Storage,从而提升二次访问速度和弱网可用性。常见策略有 Cache First、Network First、Stale While Revalidate 和 Network Only。选择策略要看资源变化频率、实时性要求和离线需求,同时要处理版本更新、缓存清理、降级和安全边界。

详细版

Service Worker 位于页面和网络之间,能代理请求。它常用于 PWA、离线缓存和二次访问加速。

策略含义适合场景
Cache First先读缓存,没缓存再请求网络带 hash 的静态资源
Network First先请求网络,失败再读缓存需要较新数据的页面
Stale While Revalidate先返回缓存,同时后台更新可接受短暂旧数据的列表
Network Only只走网络支付、提交等敏感请求
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cached => {
      return cached || fetch(event.request)
    })
  )
})

Service Worker 是性能工具,但不是安全边界;关键业务接口仍要由服务端保证权限、幂等和一致性。

完整版教学

一、Service Worker 为什么能提速

普通页面请求资源时要经过浏览器缓存和网络。Service Worker 额外提供了一层可编程代理,可以决定每个请求是走缓存、走网络,还是两者结合。

它对二次访问、弱网、离线场景特别有价值。用户再次打开页面时,核心静态资源可以直接从 Cache Storage 返回。

二、生命周期要理解

Service Worker 有 install、activate、fetch 等阶段。安装时可以预缓存关键资源,激活时可以清理旧版本缓存,fetch 时拦截请求。

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(keys =>
      Promise.all(keys.filter(k => k !== 'app-v2').map(k => caches.delete(k)))
    )
  )
})

如果不清理旧缓存,用户磁盘空间会被慢慢占用,也可能继续拿到旧资源。

三、静态资源怎么缓存

带内容 hash 的 JS、CSS、图片适合 Cache First,因为文件名变了就代表内容变了。HTML 通常不建议长期 Cache First,因为它负责引用最新资源清单。

对于静态资源,更推荐构建产物 hash + 长缓存 + SW 清理旧版本。

四、接口数据怎么缓存

接口数据要看实时性。商品分类、配置、文章列表可以用 Stale While Revalidate;用户余额、订单状态、权限信息不适合直接缓存。

错误的接口缓存会造成业务不一致,这比慢一点更严重。

五、更新策略要设计清楚

Service Worker 更新不是用户刷新一次就一定完成。新 SW 下载后通常会等待旧页面关闭。

可以根据业务选择:

  • 静默等待下次访问生效。
  • 提示用户发现新版本并刷新。
  • 在安全场景下使用 skipWaitingclients.claim,但要避免新旧资源不兼容。

六、和 HTTP 缓存的关系

Service Worker 不替代 HTTP 缓存。更合理的是两者配合:

层级作用
HTTP 缓存浏览器内建缓存协商
CDN 缓存边缘节点加速
Service Worker应用可编程缓存和离线策略

实际请求可能同时经过多层缓存,因此要避免缓存规则互相打架。

七、常见误区与追问

  • 误区:Service Worker 只要缓存越多越好。 缓存过多会占空间、增加更新复杂度,也可能返回旧数据。
  • 误区:所有接口都适合离线缓存。 强实时和敏感接口不适合直接缓存。
  • 误区:Service Worker 能解决所有首屏慢。 首次访问仍要下载和注册 SW,它更擅长二次访问和离线体验。
  • 追问:HTML 应该 Cache First 吗? 多数站点不建议长期这样做,否则用户可能拿不到最新资源入口。
  • 追问:为什么需要清理旧缓存? 防止磁盘膨胀和旧资源继续被命中。
  • 追问:SW 更新为什么有延迟? 新版本通常等待旧页面关闭后才激活,避免运行时代码被突然替换。

八、加强记忆

Service Worker 缓存记成“可编程缓存层”。静态资源偏 Cache First,实时数据偏 Network First,允许旧数据的列表可用 Stale While Revalidate;更新、清理和业务一致性必须一起设计。