service worker 运行在独立的 serviceworkerglobalscope 中,无 window/document 等 dom api,仅支持 caches、fetch、postmessage 等异步能力;其生命周期由浏览器管控,按需唤醒休眠,事件驱动执行,顶层代码仅用于注册监听器。

Service Worker 的全局执行上下文,就是它运行时的“家”——一个与页面完全隔离、独立存在的脚本环境。
它叫 ServiceWorkerGlobalScope
这个上下文不是 window,也不是 self 指向的普通对象,而是浏览器专门为其创建的 ServiceWorkerGlobalScope 实例。你在 SW 脚本里写的代码,包括所有事件监听器(如 self.addEventListener('install', ...)),都运行在这个作用域中。
-
self 就是它本身:在 SW 脚本中,
self引用的就是当前的ServiceWorkerGlobalScope,不是 window,也不等于 globalThis(在 SW 中 globalThis === self) - 没有 window、document、localStorage 等 DOM 或同步 API:这些在上下文中根本不存在,调用会直接报错
- 支持的全局属性和方法有限但精准:比如
caches、skipWaiting()、clients、registration,以及fetch、postMessage等异步能力
上下文生命周期由浏览器严格管控
它不随页面打开/关闭而启停,而是按需唤醒、空闲休眠、长期驻留:
- 注册后首次触发 install 事件时,浏览器创建该上下文并执行脚本
- 安装完成进入 waiting 状态,上下文可能被终止;激活后再次被唤起
- 当没有 fetch、message、sync 等事件待处理时,浏览器可随时回收线程,上下文暂停——下次有事件时重新初始化,但状态(如 caches、indexedDB)保留
- 整个过程对开发者透明,你只需关注事件回调逻辑,无需手动管理上下文生命周期
它不能访问 DOM,但能通信
虽然上下文里没有 document 或任何 DOM 接口,但它可以通过 postMessage 与受其控制的页面通信:
- 页面通过
navigator.serviceWorker.controller?.postMessage(...)发送消息 - SW 在
self.addEventListener('message', ...)中接收,并可反向回复 - 这种通信是异步且跨源受限的,必须确保双方 origin 一致或显式校验来源
它只响应事件,不执行顶层同步逻辑
SW 脚本加载后不会像普通 JS 那样立即执行一长串语句。浏览器只保证解析脚本,然后等待事件驱动运行:
- 顶层代码仅用于设置监听器(如 oninstall/onactivate/onfetch),不能做耗时同步操作
- 所有实际工作都在事件回调中完成,且必须返回 Promise(如用
event.waitUntil()包裹缓存逻辑) - 未被
waitUntil捕获的异步任务,可能在上下文休眠时被中断











