Service Worker 生命周期包含注册→安装→激活→更新四个核心环节:注册须在HTTPS或localhost下通过navigator.serviceWorker.register()触发;安装阶段预缓存资源并绑定版本化缓存名;激活时调用clients.claim()接管页面并清理旧缓存;更新依赖SW文件内容变更,可主动调用registration.update()触发。

Service Worker 的生命周期不是线性执行的脚本,而是一套由浏览器驱动、事件触发的状态流转机制。理解它,关键在于抓住“注册→安装→激活→更新”这四个核心环节,以及每个环节中开发者能干预的时机和方式。
注册阶段:启动生命周期的入口
这是整个流程的起点,必须在页面加载完成后的 window.addEventListener('load', ...) 中调用 navigator.serviceWorker.register()。注意三点:
- 仅 HTTPS 或 localhost 环境下才允许注册,生产环境必须部署在安全协议上
- 注册后浏览器会立即下载并解析 SW 脚本;若语法错误或网络失败,注册直接拒绝,不会进入后续阶段
- 注册成功返回 ServiceWorkerRegistration 对象,它是后续监听更新、控制缓存、触发消息的基础句柄
安装阶段:预加载与版本锚定
安装发生在注册成功后,浏览器首次解析 SW 脚本时。此时应完成资源预缓存,并通过版本号绑定缓存名,为后续更新做准备:
开发者平台元数据——GitHub、Docker Hub、crates.io 等生态系统注册表。使用此技能的时机:1. 解析 GitHub 仓库或获取其...
- 使用 event.waitUntil(caches.open(...).then(cache => cache.addAll([...])) ) 确保缓存操作完成后再进入下一阶段
- 缓存名建议包含版本标识(如 'app-v1.2.0'),避免新旧资源混存
- 通常调用 self.skipWaiting() 让新 SW 不等待当前页面关闭,立即尝试激活(尤其适用于强制更新场景)
激活阶段:接管页面与清理旧缓存
激活是 SW 开始真正生效的标志。此时它已就绪,可拦截请求、响应推送,也需主动清理历史包袱:
- 监听 activate 事件,在其中调用 clients.claim(),使当前页面立即受新 SW 控制(否则可能仍被旧 SW 管理)
- 遍历 caches.keys(),删除所有不匹配当前版本命名规则的缓存,防止磁盘占用失控
- 可在此阶段执行迁移逻辑,比如将旧缓存结构升级为新格式
更新阶段:检测差异与平滑过渡
更新不是自动重装,而是浏览器发现线上 SW 文件内容变化后,重新走一遍“注册→安装→激活”流程。控制更新节奏的核心在于:
- 每次发布新版本,必须修改 SW 文件本身(哪怕只加一行注释),否则浏览器认为无变更,不触发更新
- 前端可通过 registration.update() 主动检查更新,配合 updatefound 和 statechange 事件监听新 SW 状态
- 用户侧提示更新时,推荐先显示轻量提示,再调用 skipWaiting() + clients.matchAll().then(...).forEach(client => client.navigate(client.url)) 实现一键刷新生效

















