返回首页

Web Worker,Service Worker及Shared Worker

布莱克2026-04-01 19:17已编辑
Tip:文章封面与内容无关,作者旅游时拍摄,因为没什么值得把四季都错过!

JavaScript 引擎是单线程的,浏览器(宿主环境)是多线程的

当打开一个页面时,浏览器通常会启动以下线程:

  • GUI 渲染线程:负责解析 HTML/CSS,绘制页面。
  • JS 引擎线程:负责执行你的 JS 代码(这就是我们常说的单线程)。
  • 事件触发线程:负责管理点击、滚动等交互。
  • 定时器触发线程:负责 setTimeout 的倒计时。
  • 网络请求线程:负责处理 AJAX/Fetch 请求

当创建一个 Worker 时,浏览器会做一件特别的事:它专门为这个 Worker 又启动了一个全新的“JS 引擎线程”。

  • 独立的堆栈:Worker 拥有自己独立的执行栈和内存空间。
  • 并行的能力:因为它是操作系统层面的独立线程,所以它能和主线程同时运行在 CPU 的不同核心上

Web worker

Web Worker 的设计核心是 “完全隔离”。当执行 new Worker('task.js') 时,浏览器会为创建一个全新的 JS 执行环境

它拥有什么?(独立的)

  • 独立的 Event Loop:它有自己的宏任务和微任务队列,不会和主线程抢排队。
  • 独立的 Memory Space:它有自己的堆(Heap)和栈(Stack)。
  • 独立的全局对象 self:在 Worker 内部,没有 window,全局变量是 self(或者 globalThis)。

它没有什么?(严禁访问)

  • 无法操作 DOM:它看不见 document,也拿不到 querySelector。
  • 无法调用 UI 原生 API:比如 alert()、confirm()。
  • 无法共享内存(默认):它拿不到主线程定义的全局变量,只能通过“传话”(Messaging)来获取数据。

Service worker

Service Worker(简称 SW)最核心的能力是:拦截(Intercept)

在没有 SW 之前,网页发出的请求(Fetch/XHR)是直接去互联网的。有了 SW 之后,所有的请求都要先经过它。它像一个中间人,可以决定:

  • 直接把请求发给服务器。
  • 拦截请求,从本地缓存(Cache Storage)里掏出旧数据给网页。
  • 甚至伪造一个响应(Response)回去。

核心应用场景:离线与加速

A. 离线访问(Offline First)

当网络掉线时,SW 拦截请求并返回缓存

B. 资源预取(Precaching)

在用户还没点击下一页时,SW 已经在后台偷偷把下一页的资源下载好了

Web Worker 随页面关闭而死亡,但 Service Worker 是独立于页面生命周期

当你注册了一个 Service Worker,浏览器会把它的脚本代码和它开辟的 Cache Storage(缓存库) 永久保存在用户的本地磁盘上。

  • 即使你关掉了浏览器:这个 SW 的配置信息依然在浏览器的系统文件中。
  • 即使你重启了电脑:只要你不手动清理浏览器缓存,它依然在那里“待命”
  • 休眠(Idle/Terminated):当你关闭所有标签页,且没有任务处理时,浏览器会杀掉 Service Worker 的运行进程。此时它不占内存。
  • 唤醒(Waking Up):当以下“闹钟”响起时,浏览器会瞬间把 Service Worker 从硬盘加载到内存里运行:

       用户再次打开网页:它立刻跳出来拦截第一个 fetch 请求。

       收到服务器推送(Push):即使网页没开,服务器发来个通知,SW 也会醒来弹出提示。

       后台同步(Sync):你之前没发出去的评论,在网络恢复的一刻,SW 自动醒来帮你在后台发出去。

Shared worker



assistant