JavaScript Service Worker高级应用

Service Worker通过拦截请求、管理缓存、后台同步与消息推送,实现PWA的高级功能。1. 可采用Cache-First、Stale-While-Revalidate等策略精细化控制资源缓存;2. 通过fetch事件实现路由拦截与代理转发,支持微前端与灰度发布;3. 利用Background Sync在网络恢复后自动重试失败操作;4. 通过Push API实现页面外的消息通知;5. 使用版本化缓存命名与activate事件清理旧缓存,确保更新原子性。

Service Worker 不只是离线缓存的工具,它在现代 Web 应用中扮演着越来越重要的角色。通过拦截网络请求、管理缓存策略、实现后台同步与消息推送,我们可以构建出接近原生体验的 Progressive Web App(PWA)。以下是几个 Service Worker 的高级应用场景和实现技巧。

1. 精细化资源缓存控制

除了常见的缓存静态资源,我们可以通过不同策略对动态内容进行智能缓存:

  • Cache-First + Network Fallback: 对图片、字体等资源优先使用缓存,网络请求仅作为更新备用。
  • Stale-While-Revalidate: 立即返回缓存内容,同时在后台发起请求更新缓存,提升响应速度。
  • Network-Only 按需缓存: 对用户登录态或敏感数据不缓存,确保安全性。

示例代码:

self.addEventListener('fetch', event => {
  const { request } = event;
  const url = new URL(request.url);

if (url.pathname.endsWith('.jpg')) { event.respondWith( caches.match(request).then(cached => { const networkFetch = fetch(request).then(response => { if (response.ok) { caches.open('image-cache').then(cache => cache.put(request, response)); } }); return cached || networkFetch; }) ); } });

2. 路由化请求拦截与代理转发

利用 Service Worker 可以实现前端“软路由”,将特定请求重定向或代理到其他地址,适用于微前端或灰度发布场景。

  • 拦截 API 请求,根据环境变量切换后端接口地址。
  • 将 /beta/* 路径请求代理到测试服务器。
  • 模拟接口返回,用于开发调试。

实现方式:在 fetch 事件中判断 URL,构造自定义 Response 或修改 request.clone() 后重新发起请求。

3. 后台同步(Background Sync)

在网络不稳定时,用户操作可能失败。通过 Background Sync,可以延迟执行关键请求,待网络恢复后自动重试。

  • 注册 sync 事件:navigator.serviceWorker.ready.then(reg => reg.sync.register('submit-data'));
  • 在 Service Worker 中监听 sync 事件并处理任务队列。
  • 适合提交表单、发送日志等非即时性操作。

注意:该功能依赖浏览器唤醒机制,并非实时执行。

4. 消息推送与通知(Push & Notification)

即使页面未打开,也能通过 Push API 接收服务器消息,并显示系统级通知。

  • 申请通知权限并获取 Push 订阅信息。
  • 将 endpoint 发送给服务端用于推送。
  • 在 Service Worker 中监听 push 事件并显示 notification。
self.addEventListener('push', event => {
  const data = event.data.json();
  event.waitUntil(
    self.registration.showNotification(data.title, {
      body: data.body,
      icon: '/icon.png'
    })
  );
});

5. 缓存版本管理与原子更新

避免缓存污染和旧版本残留,推荐使用基于时间戳或版本号的缓存命名策略。

  • install 阶段预缓存新资源,activate 阶段清理旧缓存。
  • 使用 Cache Storage API 动态管理多个缓存组。
  • 结合 Webpack 或 Workbox 实现自动化版本控制。

核心逻辑:在 activate 事件中调用 event.waitUntil(caches.delete(oldCache)) 清理过期缓存。

基本上就这些实用的高级用法。掌握它们能显著提升应用的健壮性和用户体验,尤其是在弱网或移动环境下。