JavaScript 里的 Web Workers:完整指南
来源:dev.to — 2026-09-07
📋 概述
在一页正解析 5 万行 CSV 时拖一个滑块,整整一秒没反应——不是滑块代码慢,它根本没运行。浏览器的单线程正忙于你的解析循环,在它返回前,没有点击、滚动或重绘能轮到执行。修复方案已随每个现代浏览器内置:一个叫 Web Worker 的第二线程,运行你的代码而绝不碰页面 UI 依赖的那条主线程。本文是逐步指南:从最小的 worker 到模块 worker、transferable 对象、清理终止、陷阱与最佳实践。
🔑 核心要点
- 为什么存在:浏览器 JavaScript 跑在单主线程,而同一线程还负责解析 HTML、计算样式、布局绘制与响应输入——你的代码运行时一切都等着;setTimeout(fn,0) 也无济于事,它只是把冻结延后而非移除
- 心智模型:worker 是并行运行的独立 JS 环境、与页面不共享内存,唯一出入口是经由消息通道发送数据的副本——像两间无共享家具的房间通过信箱传纸条,跨过去的是结构化克隆的副本而非引用
- 数据只以副本或转移两种形式跨越:函数与 DOM 节点永不能跨(不可克隆),ArrayBuffer 等可转移类型用第二个参数显式转移所有权——转移后原引用 byteLength 变 0,对 200MB 缓冲区几乎免费
- 清理不能省:worker 会一直运行并占内存直到你显式停它——worker.terminate() 即时无条件(正在做的工作被直接丢弃、finally 不保证跑),self.close() 是 worker 自停;组件卸载/取消按钮处务必配对 terminate
- edge cases:worker 永不能碰 DOM(发 DOM 节点抛 DataCloneError)、worker 内未捕获异常不抛在主线程而触发 onerror 事件、new Worker 必须同源(blob: URL 算同源)、启动有真实开销——毫秒级任务不值得,重活或反复任务才划算
💡 金句
The fix already ships in every browser you support: a second thread that runs your code without ever touching the one thread the page's UI depends on.
👍 0
👎 0
← 返回 dev.to 首页