Web Worker

一、JS 单线程困境

  1. JS 是单线程:所有任务在主线程排队,无法并行。
  2. 阻塞问题:耗时计算会阻塞 UI 渲染、交互,导致页面卡顿、掉帧。
  3. 设计原因:保证 DOM 操作原子性,避免多线程竞态冲突。

二、Web Worker 是什么

  • 允许 JS 创建独立后台线程,不阻塞主线程。
  • 专门处理耗时计算、大数据处理
  • 主线程负责 UI,Worker 负责计算,真正并行

三、核心能力与限制

✅ 能做

  • 复杂计算、循环、数据处理
  • fetch / XHR 网络请求
  • setTimeout / setInterval
  • PromiseIndexedDBWebSocket

❌ 不能做(禁区)

  • 不能操作 DOM(无 document、window)
  • 不能用 localStorage / sessionStorage
  • 不能用 alert / confirm

四、通信机制

  1. 主线程 ↔ Worker 线程 通过 postMessage 通信。
  2. 传值不传址 :使用结构化克隆算法,深拷贝传递,不共享内存,线程安全。
  3. 接收数据用 onmessageaddEventListener('message')

五、创建与使用

js 复制代码
// 主线程
const worker = new Worker('./task.js', { type: 'module' })
worker.postMessage(data)
worker.onmessage = (e) => { /* 接收结果 */ }
js 复制代码
// worker.js
self.onmessage = (e) => {
  // 处理耗时任务
  self.postMessage(result)
}

六、关闭线程(生命周期)

  1. 主线程强制关闭

    js

    js 复制代码
    worker.terminate()

    立即停止,可能丢失数据。

  2. Worker 内部优雅关闭

    js

    js 复制代码
    self.close()

    完成当前任务后关闭,更安全。


七、错误处理

  • onerror:监听 Worker 内部运行错误。
  • onmessageerror:监听数据序列化 / 解析失败。

八、模块化与依赖

  1. 传统方式importScripts('./a.js', './b.js')
  2. ES 模块new Worker('task.js', { type: 'module' }),支持 import/export

九、SharedWorker(共享线程)

  1. 同源多标签页共享同一个线程
  2. 用于:跨页通信、状态同步、共享计算。
  3. 基于 port 通信,需监听 connect 事件。
  4. 典型场景:多标签页同步计数、音乐播放状态、在线文档协同。

十、结构化克隆算法

  • 比 JSON 更强:支持 DateRegExpBlobArrayBuffer、循环引用。
  • 不能克隆:Function、Error、DOM 节点。
  • Transferable:二进制数据可转移所有权,零拷贝,性能极高。

十一、最佳使用场景

  • 大量数据计算、解析、排序、加密解密
  • 图像处理、Canvas 数据计算
  • 长循环、大数据遍历
  • 多页面状态同步(SharedWorker)

十二、总结

Web Worker = 浏览器给 JS 开的后台计算线程,不卡 UI、不碰 DOM、靠消息通信、传值不传址。

相关推荐
LucianaiB11 分钟前
【Dify + EdgeOne】你奶奶也会做一个“智票通”,轻松票据自定义提取+防数据泄露
前端·后端
python在学ing15 分钟前
前端-CSS学习笔记
前端·css·python·学习
Bug-制造者27 分钟前
【Vue3 实战】全局错误处理体系搭建:实现业务与错误彻底解耦
前端·javascript·vue.js
悟空瞎说30 分钟前
# Git 交互式变基:优雅整理提交历史,告别杂乱 PR 记录
前端·git
学习,学习,在学习31 分钟前
Qt工控仪器程序框架设计详解(工控多仪器控制版本)
开发语言·c++·qt
三品吉他手会点灯37 分钟前
C语言学习笔记 - 35.数据类型 - printf函数的非输出控制符与格式优化
c语言·开发语言·笔记·学习
竹林81840 分钟前
从ethers.js迁移到Viem:我在DeFi Dashboard项目中踩过的坑与最终方案
javascript
还有多久拿退休金43 分钟前
DragSortTable:一个让我怀疑人生的滚动重置 Bug
前端
zithern_juejin1 小时前
ES6——Promise
javascript
渐儿1 小时前
组件库开发入门到生产(从零封装到 npm 发布)
前端