Service Worker 缓存

197 阅读3分钟

Service Worker 是什么,以及它怎么解决 WebView 缓存不稳定的问题。


Service Worker 是什么?

Service Worker(SW) 是浏览器在后台独立运行的一个脚本,它就像一个“网页的隐形管家”,可以拦截网络请求、缓存资源,甚至让你的网页离线也能正常使用。

关键特点:

  1. 独立于网页运行
    • 即使你关闭了网页标签,Service Worker 仍然可以在后台工作(比如接收推送通知)。
  2. 能控制网络请求
    • 可以拦截页面的所有 HTTP 请求,决定是从缓存返回还是去网络请求。
  3. 支持离线缓存
    • 即使没网,也能让网页部分或全部正常工作(比如看之前加载过的文章)。
  4. 需要 HTTPS(本地开发除外)
    • 出于安全考虑,正式环境必须用 HTTPS,但本地调试(localhost)可以用 HTTP。

Service Worker 如何解决 WebView 缓存问题?

WebView 的缓存是临时的,可能被系统随意清理,而 Service Worker 的缓存是持久化的,除非手动清除,否则不会轻易丢失。

对比 WebView 缓存 vs Service Worker 缓存

特性WebView 缓存Service Worker 缓存
存储位置临时内存/磁盘,可能被系统清理独立存储,持久化
控制权由系统/WebView 管理开发者完全控制
离线可用性弱,缓存可能失效强,可定制离线策略
适用场景普通网页临时缓存PWA(渐进式网页应用)、离线应用

Service Worker 的工作原理

  1. 注册
    网页加载时,先注册 Service Worker:

    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/sw.js')
        .then(() => console.log('SW 注册成功!'))
        .catch(err => console.log('SW 注册失败:', err));
    }
    
    • sw.js 是 Service Worker 的脚本文件,控制缓存和请求。
  2. 安装(Install)
    Service Worker 第一次注册时触发,通常在这里预缓存关键资源:

    self.addEventListener('install', (event) => {
      event.waitUntil(
        caches.open('my-cache-v1').then((cache) => {
          return cache.addAll([
            '/',
            '/index.html',
            '/styles.css',
            '/app.js',
            '/logo.png'
          ]);
        })
      );
    });
    
  3. 拦截请求(Fetch)
    可以决定是从缓存返回,还是去网络请求:

    self.addEventListener('fetch', (event) => {
      event.respondWith(
        caches.match(event.request)
          .then((response) => {
            // 如果缓存有,直接返回
            if (response) return response;
            // 否则去网络请求
            return fetch(event.request);
          })
      );
    });
    
  4. 更新机制

    • 如果 sw.js 文件内容变化,浏览器会自动检测并安装新版本。
    • 旧版本仍运行,直到所有页面关闭,新版本才会接管(可手动跳过等待)。

Service Worker 的适用场景

  1. PWA(渐进式网页应用)
    • 让网页像原生 App 一样离线可用(比如 Twitter Lite、Pinterest PWA)。
  2. 加速重复访问
    • 缓存静态资源(CSS/JS/图片),下次访问秒开。
  3. 后台数据同步
    • 即使用户关闭网页,也能在后台同步数据(比如邮件客户端)。
  4. 推送通知(Push API)
    • 即使用户没打开网页,也能收到通知(比如新闻提醒)。

Service Worker 的局限性

  • 不能直接访问 DOM(但可以通过 postMessage 和页面通信)。
  • 需要 HTTPS(生产环境必须,localhost 除外)。
  • 缓存管理要谨慎,如果策略没写好,可能导致用户一直用旧版本。

总结

  • Service Worker = 网页的隐形管家,能缓存资源、拦截请求、支持离线。
  • 比 WebView 缓存更可靠,因为缓存持久化,开发者可控。
  • 适合 PWA、离线应用、加速网页,但需要 HTTPS 和合理缓存策略。

如果你的网页在 WebView 里缓存总被清理,用 Service Worker 可以大幅提升稳定性! 🚀