news 2026/6/23 16:24:56

ServiceWorker 的生命周期包含6种核心状态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ServiceWorker 的生命周期包含6种核心状态

Service Worker 规范中明确定义的 6 种内部状态(internal states)

这些状态描述了 Service Worker 线程在其生命周期中的不同阶段。以下是基于规范(如 W3C 和 WHATWG 标准)整理的表格,准确对应这六种状态:

序号状态(英文)状态(中文)说明
1parsed已解析浏览器成功解析注册的 Service Worker 脚本,但尚未开始安装。这是注册后的初始状态。
2installing安装中正在执行install事件。开发者通常在此阶段缓存静态资源。若脚本未改变,此状态可能跳过。
3installed已安装安装成功完成,但尚未激活。此时 Service Worker 处于“等待”状态(waiting),尤其当已有旧版正在控制页面时。
4activating激活中正在执行activate事件。通常用于清理旧缓存或迁移数据。
5activated已激活Service Worker 已激活并开始控制其作用域内的页面(仅对新导航或刷新后的页面生效),可拦截fetch、处理推送等事件。
6redundant已失效(冗余)Service Worker 被废弃。可能原因包括:安装失败、被新版本取代、注册被注销(unregister),或脚本内容与已安装版本不一致导致回退。

补充说明:

  • 这些状态是Service Worker 内部状态(internal state),可通过ServiceWorker.state属性读取(例如navigator.serviceWorker.controller?.state)。
  • 状态转换是单向的(除异常情况外):
    parsedinstallinginstalledactivatingactivated
    或在任一阶段失败/被取代 →redundant
  • 开发者可通过监听statechange事件跟踪状态变化:

此六状态模型是理解 Service Worker 生命周期和调试更新行为的核心依据。


Service Worker 生命周期

阶段状态说明
1. 注册(Registration)installing(若首次注册)通过navigator.serviceWorker.register()注册 Service Worker 脚本。浏览器下载脚本并准备安装。
2. 安装(Installing)installing触发install事件。在此阶段可缓存静态资源(如通过 Cache API)。若安装成功,进入“已安装”状态;若失败(如缓存失败),则进入“冗余(redundant)”状态。
3. 已安装 / 等待激活(Installed / Waiting)waiting安装成功但尚未激活。如果已有旧版 Service Worker 正在控制客户端,则新版本会等待(除非调用skipWaiting())。
4. 激活(Activating)activating触发activate事件。通常用于清理旧缓存或执行迁移逻辑。激活后,Service Worker 开始控制页面(仅对新打开/刷新的页面生效)。
5. 已激活(Activated)activeService Worker 处于活跃状态,可拦截fetchpushsync等事件,处理网络请求和后台任务。
6. 冗余(Redundant)redundantService Worker 被废弃,原因可能包括:安装失败、被新版本取代、或注册被注销。此时不再接收事件。

💡补充说明

  • 页面必须通过 HTTPS(或 localhost)才能使用 Service Worker。
  • Service Worker 的作用域(scope)由注册时的路径决定。
  • 只有当所有受控页面关闭或新版本接管后,旧 Service Worker 才会被替换。

该生命周期确保了 Web 应用更新的平滑过渡与离线能力的可靠实现。


完整的注册函数

async function registerServiceWorker() { if (!('serviceWorker' in navigator)) { console.warn('当前浏览器不支持 Service Worker'); return; } try { const registration = await navigator.serviceWorker.register('./js/serviceWorker.js', { //scope: '/', // 控制范围 updateViaCache: 'none' // 控制更新行为 }); console.log('Service Worker 注册成功,作用域:', registration.scope); // 监听生命周期 trackServiceWorkerLifecycle(registration); // 监听控制器变化 navigator.serviceWorker.addEventListener('controllerchange', () => { console.log('页面控制器已变更,可能需要刷新页面'); }); return registration; } catch (error) { console.error('Service Worker 注册失败:', error); throw error; } } function trackServiceWorkerLifecycle(registration) { const logState = (worker, label = 'Worker') => { if (!worker) return; const log = (message) => console.log(`${label}: ${message}`); log(`初始状态: ${worker.state}`); worker.addEventListener('statechange', () => { log(`状态变为: ${worker.state}`); switch (worker.state) { case 'installed': if (registration.waiting) { log('已安装,等待激活'); // 可以在这里提示用户刷新页面 } break; case 'activated': log('已激活,可以控制页面'); break; case 'redundant': log('已废弃,被新版本替换'); break; } }); }; // 监听现有 worker if (registration.installing) logState(registration.installing, 'Installing'); if (registration.waiting) logState(registration.waiting, 'Waiting'); if (registration.active) logState(registration.active, 'Active'); // 监听新 worker 安装 registration.addEventListener('updatefound', () => { console.log('开始安装新版本的 Service Worker'); logState(registration.installing, 'New Installing'); }); } // 使用示例 window.addEventListener('load', () => { registerServiceWorker().then(registration => { // 可以在这里添加更多逻辑 }); });

更新检查

// 检查 Service Worker 更新 function checkForUpdates() { if (!navigator.serviceWorker || !navigator.serviceWorker.controller) { return; } navigator.serviceWorker.ready.then((registration) => { registration.update().then(() => { if (registration.waiting) { console.log('有新的 Service Worker 等待激活'); // 可以提示用户刷新页面 showUpdateNotification(); } }); }); } // 提示用户刷新 function showUpdateNotification() { if (confirm('有新的版本可用,是否立即刷新?')) { navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' }); window.location.reload(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 8:59:21

网易云NCM文件终极解密:从加密音乐到自由播放的完整方案

网易云NCM文件终极解密:从加密音乐到自由播放的完整方案 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾在网易云音乐下载了心爱的歌曲,却发现文件后缀是神秘的.ncm格式,无法在其他设备上…

作者头像 李华
网站建设 2026/6/22 14:15:39

Betaflight与F4/F7飞控硬件兼容性:核心要点

Betaflight飞控选型实战:F4与F7到底差在哪?你有没有过这样的经历?刷完一波新固件更新日志,满心欢喜地打开Betaflight Configurator,准备启用“动态陷波8kHz Dshot”组合技,结果刚一保存配置,飞控…

作者头像 李华
网站建设 2026/6/13 12:33:13

猫抓Cat-Catch资源嗅探工具完整教程:从新手到高手

猫抓Cat-Catch资源嗅探工具完整教程:从新手到高手 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为无法保存心爱的在线视频而烦恼吗?猫抓Cat-Catch作为一款强大的资源嗅探…

作者头像 李华
网站建设 2026/6/23 9:59:28

猫抓Cat-Catch:新手必学的网页视频下载全攻略

猫抓Cat-Catch:新手必学的网页视频下载全攻略 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为心仪的在线视频无法保存而烦恼吗?猫抓Cat-Catch作为一款专为网页媒体资源设…

作者头像 李华
网站建设 2026/6/22 14:46:10

Expo CLI常用命令详解:完整指南

Expo CLI 实战手册:从零构建到上线发布的全流程精解 你是否经历过这样的开发日常?刚搭建好 React Native 环境,Xcode 编译失败、Android SDK 路径报错;改了几行代码要等三分钟重新打包;修复一个紧急 bug 却不得不走一…

作者头像 李华
网站建设 2026/6/23 2:49:51

RePKG终极指南:5分钟掌握Wallpaper Engine资源提取与转换

RePKG终极指南:5分钟掌握Wallpaper Engine资源提取与转换 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 想要深入探索Wallpaper Engine壁纸的奥秘吗?RePKG就…

作者头像 李华