Web Workers可在后台线程执行js避免卡顿,主线程负责ui,通过postMessage异步通信传递数据副本,支持Transferable Objects零拷贝传输,需监听Error处理错误并调用terminate释放资源,适用于大数据、加密等计算,但无法访问dom。
Web Workers 是浏览器提供的多线程能力,让你在后台线程中运行 javaScript 代码,避免耗时计算卡住页面。主线程负责渲染和用户交互,一旦被密集计算占用,页面就会卡顿甚至无响应。通过 Web Workers,可以把这些任务移出主线程。
创建和使用 Web Worker
要启动一个 Web Worker,需要将计算逻辑写进一个独立的 JS 文件,然后在主脚本中实例化 Worker。
例如,创建文件 worker.js:
self.onmessage = function(e) { const data = e.data; // 执行密集型计算,比如大数组排序或数学运算 const result = heavyComputation(data); self.postMessage(result); };
function heavyComputation(arr) { return arr.map(x => math.sqrt(x * x + 1)).sort((a, b) => a - b); }
在主线程中(如 main.js)调用:
const worker = new Worker('worker.js');
worker.onmessage = function(e) { console.log('计算结果:', e.data); // 更新 UI };
// 发送数据给 Worker worker.postMessage([100, 200, 300, 400, 500]);
传递数据与通信机制
主线程和 Worker 之间通过 postMessage 发送数据,通过监听 onmessage 接收结果。这种通信是异步的,不会阻塞界面。
注意:传递的数据是**副本**(结构化克隆),不是引用。大数据量传输会有开销,建议只传必要数据。
如果处理大量数组,可考虑使用 Transferable Objects,比如 ArrayBuffer,实现零拷贝传输:
const arrayBuffer = new ArrayBuffer(1024); worker.postMessage(arrayBuffer, [arrayBuffer]); // 第二个参数转移所有权
错误处理与终止 Worker
worker.onerror = function(error) { console.error('Worker 错误:', error.message); };
任务完成或不再需要时,应手动关闭 Worker 释放资源:
worker.terminate(); // 立即终止
适用场景与限制
适合使用 Web Workers 的场景包括:
但 Web Workers 不能访问 DOM、window 或 document 对象,所有涉及 UI 操作仍需回到主线程。
基本上就这些。合理使用 Web Workers,能让复杂计算流畅运行,同时保持页面响应灵敏。不复杂但容易忽略的是及时清理和控制通信频率。