news 2026/4/3 3:31:16

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/3/27 17:42:34

Bypass Paywalls Clean完全指南:5步突破付费内容限制

Bypass Paywalls Clean完全指南:5步突破付费内容限制 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 你是否经常遇到这样的困扰?想阅读深度报道却被付费墙阻挡…

作者头像 李华
网站建设 2026/4/2 17:59:11

Open-AutoGLM开源:为什么它将成为AI开发者今年最稀缺的技术资源?

第一章:Open-AutoGLM开源:AI开发者的新纪元Open-AutoGLM 的开源标志着人工智能开发进入一个全新的协作与创新阶段。作为一个面向生成语言模型自动化优化的开源框架,Open-AutoGLM 提供了从模型微调、提示工程到推理部署的一体化工具链&#xf…

作者头像 李华
网站建设 2026/3/11 14:24:23

突破内容限制的终极指南:5大技巧让你轻松访问受限内容

在信息爆炸的时代,你是否曾经因为内容限制而无法获取重要的新闻资讯、学术论文或商业报告?这种信息获取的障碍正在影响着无数用户的学习、工作和研究。今天,我将为你详细介绍一款能够有效解决这一问题的浏览器扩展工具,帮助你重新…

作者头像 李华
网站建设 2026/3/29 8:00:51

【Spring】核心类研究价值排行榜

Spring核心类研究价值排行榜(按使用频率) 以下是企业级开发中最值得深入研究的Spring核心类,按实际使用频率从极高频到低频分层梳理:一、极高频类类名核心作用典型应用场景DispatcherServletSpring MVC核心前端控制器,…

作者头像 李华
网站建设 2026/3/29 20:12:54

终极指南:如何用Python脚本5分钟搞定大麦网自动抢票

终极指南:如何用Python脚本5分钟搞定大麦网自动抢票 【免费下载链接】DamaiHelper 大麦网演唱会演出抢票脚本。 项目地址: https://gitcode.com/gh_mirrors/dama/DamaiHelper 还在为抢不到心仪演唱会门票而烦恼吗?今天分享一个基于Python和Seleni…

作者头像 李华
网站建设 2026/3/27 14:38:11

数字内容访问工具终极指南:5种方案实现免费阅读

在当今信息爆炸的时代,你是否经常遇到想要阅读的文章被付费墙挡住?无论是新闻网站的专业分析,还是技术博客的深度教程,付费墙已经成为获取优质内容的主要障碍。本文将为你详细介绍5种有效的数字内容访问方案,帮助你突破…

作者头像 李华