当前位置: 首页 > news >正文

Web Worker 从原理到实战 —— 把耗时工作搬到后台线程,避免页面卡顿


摘要:JavaScript 是单线程的,这句话的意思是指默认执行时是所有代码都在js主要线程运行,遇到复杂计算或频繁序列化会阻塞页面。Web Worker 提供后台线程能力,把耗时任务交给子线程处理,从而保持 UI 流畅。本文从原理讲起,逐步展示基础用法、进阶技巧和常见场景,最后结合 IM 消息缓存的实战,在我真实项目中手写pina插件存入indexdb也有使用过Web Worker 后续会分享,帮助你把 Worker 真正用到业务中。


1. 为什么需要 Web Worker

JavaScript 的执行基于事件循环,主线程既负责脚本也负责渲染。当主线程被大量计算或 IO 占用时,页面就会卡顿。
解决方案:把这些与 DOM 无关的耗时工作交给 Web Worker。


2. Web Worker 的核心原理

  • 线程隔离:Worker 无法直接访问 DOM。
  • 消息传递:主线程与 Worker 通过 postMessage / onmessage 通信。
  • 结构化克隆:消息会被复制,开销较大。
  • Transferable:支持零拷贝传输大数据。
  • 生命周期new Worker() 创建,terminate()self.close() 结束。

3. 最简用法

worker.js

self.onmessage = (e) => {const n = e.data;let sum = 0;for (let i = 0; i < n; i++) sum += i;postMessage(sum);
};

index.html

<script>const worker = new Worker('worker.js');worker.onmessage = (e) => {console.log('结果:', e.data);};worker.postMessage(100000000);
</script>

现代打包工具可用:

const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' });

4. 进阶技巧

Blob 动态创建

const code = `self.onmessage = e => {const arr = e.data;postMessage(arr.sort((a,b) => a - b));};
`;
const blob = new Blob([code], { type: 'text/javascript' });
const url = URL.createObjectURL(blob);
const worker = new Worker(url);

Transferable

const buffer = new ArrayBuffer(1024 * 1024 * 10);
worker.postMessage({ buffer }, [buffer]); 

SharedArrayBuffer

适合极端性能需求,但需服务端安全头(COOP/COEP),一般项目少用。


5. Worker 池

减少频繁创建/销毁开销,适合高并发任务。

import { WorkerPool } from './workerPool';const pool = new WorkerPool(new URL('./taskWorker.js', import.meta.url), 3);
const results = await Promise.all(inputs.map(i => pool.exec(i)));
pool.terminate();

(WorkerPool 的实现见文中完整代码,可直接复制使用)


6. 适用与避免场景

适用

  • 大数组/矩阵计算
  • 图像处理、加解密、音视频转码
  • 大量序列化(JSON/Protobuf)
  • 文件解析、批量 IndexedDB 写入

避免

  • 需要直接操作 DOM
  • 短小任务(创建 Worker 成本更高)

7. 实战:IM 消息缓存(IndexedDB)

即时通讯应用中,断网恢复或拉历史消息时需要批量写入本地 IndexedDB。直接在主线程操作会卡顿,将逻辑放到 Worker 更流畅。

dbWorker.js

self.onmessage = async (ev) => {const { cmd, payload } = ev.data;const db = await openDb();if (cmd === 'bulkSave') {await putMany(db, payload);postMessage({ cmd, ok: true });} else if (cmd === 'getAll') {const list = await getAll(db);postMessage({ cmd, ok: true, data: list });}
};

主线程调用

const dbWorker = new Worker('dbWorker.js');
dbWorker.onmessage = (e) => {if (e.data.cmd === 'bulkSave') console.log('保存完成');if (e.data.cmd === 'getAll') renderMessages(e.data.data);
};dbWorker.postMessage({ cmd: 'bulkSave', payload: msgs });
dbWorker.postMessage({ cmd: 'getAll' });

这样,UI 渲染和输入始终保持流畅。


8. 常见坑与调试

  • 忘记 terminate() 导致内存泄漏
  • 频繁创建/销毁 Worker 性能差
  • 误用 Transferable 导致原对象被清空
  • 在 Worker 中访问 DOM(不可行)

调试方法:

  • Chrome DevTools 查看 Worker 线程
  • 在 Worker 内打印日志或发回进度消息
  • 使用 Performance 面板确认主线程是否减轻阻塞

结语

Web Worker 是浏览器提供的原生多线程能力。它的价值在于把重计算/大量 IO移到后台线程,让主线程专注渲染与交互。
正确使用 Worker,可以让应用在大数据处理、IM 消息缓存、复杂计算中依然保持流畅。



文章转载自:

http://gzJoLymm.cdrzw.cn
http://KEDkum1k.cdrzw.cn
http://FdqiVWwc.cdrzw.cn
http://2SuZBca4.cdrzw.cn
http://cQNGqmAx.cdrzw.cn
http://EK8sTjIm.cdrzw.cn
http://N9CzBr9P.cdrzw.cn
http://E9Oww322.cdrzw.cn
http://GSraTpqX.cdrzw.cn
http://S8soPsdT.cdrzw.cn
http://xUTkxDSY.cdrzw.cn
http://1flEfehX.cdrzw.cn
http://gWkHYItP.cdrzw.cn
http://sQkIcIhT.cdrzw.cn
http://HegG4TBs.cdrzw.cn
http://grcroknX.cdrzw.cn
http://3QRm3urZ.cdrzw.cn
http://oW3Bosag.cdrzw.cn
http://00S21ofw.cdrzw.cn
http://GsxAad3L.cdrzw.cn
http://g5P3DSwA.cdrzw.cn
http://eygPvUBW.cdrzw.cn
http://lvPSRvZy.cdrzw.cn
http://ddPohM5L.cdrzw.cn
http://wFAeX9Bt.cdrzw.cn
http://MymYfpZZ.cdrzw.cn
http://oDhWRazd.cdrzw.cn
http://8QucEtkH.cdrzw.cn
http://LESHKiYv.cdrzw.cn
http://DLZjsFL5.cdrzw.cn
http://www.dtcms.com/a/370431.html

相关文章:

  • [网络入侵AI检测] docs | 任务二分类与多分类
  • Browser Use:打造你的浏览器自动化助手
  • 全维度质量保障:捷多邦厚铜板控制方法详解
  • PDF文件基础-计算机字体
  • Python 制作的一个小说在线阅读工具
  • 携程社招前端面经
  • 基于扰动观察法(PO)的光伏最大跟踪策略Simulink
  • 提示语规则引擎:spring-ai整合liteflow
  • 少儿舞蹈小程序(9)校区信息展示
  • EG2103 SOP-8 内置600V功率MOS管 栅极驱动芯片
  • 【目录-判断】鸿蒙HarmonyOS开发者基础
  • 实体商业创新观察:AI 驱动的本地生活服务新模式解析
  • ThinkPHP 6框架常见错误:htmlentities()函数参数类型问题解决
  • 【Big Data】Apache Kafka 分布式流处理平台的实时处理实践与洞察
  • 大模型服务之下的新旧政务智能系统比较
  • 贪心算法应用:流行病干预策略问题详解
  • 雪球科技Java开发工程师笔试题
  • 【pyhton】函数
  • 进阶向:密码生成与管理工具
  • SWEET:大语言模型的选择性水印
  • 基于Transformer的交通流预测和拥堵识别模型
  • STM32——Flash闪存
  • 【ComfyUI】深度 ControlNet 深度信息引导生成
  • 444444
  • 固定资产管理系统(vue+Springboot+mybatis)
  • 永磁同步电机 FOC 控制中 d、q 轴杂谈与角度偏移影响
  • 网络编程(5)Modbus
  • 蓓韵安禧DHA纯植物藻油纯净安全零添加守护母婴健康
  • SAP二次开发指南:个性化与稳定性的平衡技巧
  • MAZANOKE与cpolar:打造安全可控的照片云端管理系统