news 2026/7/22 3:00:33

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/7/19 19:12:23

cpp lambda vs 仿函数

Lambda表达式不一定比仿函数快,二者性能差异主要源于编译器优化策略1. 无捕获Lambda可被隐式转换为函数指针,或直接作为模板参数实例化,编译器能更轻松地做内联优化(消除函数调用开销);而传统仿函数的 oper…

作者头像 李华
网站建设 2026/7/21 7:48:10

ncmdump音乐解放神器:一键解锁数字音乐格式限制

你是否曾经在音乐平台下载了心爱的歌曲,却发现在其他设备上无法播放?这种"格式不兼容"的困扰正是NCM格式设下的数字围墙。今天,让我们一同探索ncmdump这个神奇工具,它能轻松处理音乐文件,让你的音乐真正属于…

作者头像 李华
网站建设 2026/7/20 15:23:43

Chrome付费墙绕过工具终极指南:简单5步解锁全网付费内容

Chrome付费墙绕过工具终极指南:简单5步解锁全网付费内容 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的时代,你是否也曾为付费墙而烦恼&#xff…

作者头像 李华
网站建设 2026/7/20 21:02:47

Bypass Paywalls Clean终极指南:3分钟解锁150+付费新闻网站

在数字信息时代,优质内容往往被付费墙层层封锁。Bypass Paywalls Clean作为一款专业的浏览器扩展工具,能够智能绕过全球主流新闻网站的付费限制,让您轻松获取完整阅读体验。这款工具以其卓越的技术性能和用户友好的设计理念,成为无…

作者头像 李华
网站建设 2026/7/17 0:35:46

大麦抢票神器:DamaiHelper全自动解决方案完全指南

还在为抢不到心仪演唱会的门票而烦恼吗?面对秒光的票务市场,手动操作已经难以应对。现在,DamaiHelper这款基于PythonSelenium开发的智能抢票工具,将为你带来全新的购票体验,让你轻松拥有热门演出的入场券。 【免费下载…

作者头像 李华