web workers 快速入门,了解一下其理解和运用
- 高效
- 并行
- 浏览器是单线程的, 任何需要高性能计算的 js 任务都会阻塞主线程的执行,浏览器任何操作都会失效,web workers 将耗时的任务拆出去,降低主线程的压力,不过 CPU 资源也是有限的,其不能增加总体运行效率,只是在不同线程间进行执行而已。
const workers = new Worker("../src/worker.js") // 代表worker是一个web worker实例,执行路径下的文件
-
web workers 用来执行异步脚本,只要掌握了与主线程通信的方式,就可以指定时机运行异步脚本,并在运行完将结果传递给主线程。
-
主线程接受发 web worker 消息
const workers = new Worker("../src/worker.js") worker.onmessage = e = {} // 通过onmessage 接收信息 worker.postMessage('hello') // 通过postMessage 发送消息
-
web worker 收发主线程消息也类似
self.onmessage = e = {} self.postMessage('great')
-
销毁 web workers
worker.terminate()
- 将对象引用零成本转交给 web worker 的上下文,无需做结构拷贝,主线程和 web workers 之间的通信不是对象引用传递,而是与进程服务交互类似,需要做序列化/反序列化,对象十分庞大时,这种操作也会消耗大量计算资源,降低运行速率。
- 对象引用方式十分简单,将 postMessage 添加第二个参数,将序列化的对象引用传过去就可以了
- webpack 插件,worker-loader,将普通 JS 文件全部依赖提取打包然后替换调用处,以 Blob 形式内联在源码中
- blob-url
-
架构设计上 web worker 就要行程队列,调用 postMessage 的时候,对应的 web worker 不一定已经完成初始化,浏览器底层要维护一个队列,在其初始化完成后才去消费 postMessage,保证都能将传输的数据接收到。
-
受手动维护队列的因素:
- 业务原因:实时性较高,来不及消费的 postMessage 就不要发送新的消息,需要通过双向通信拿到 web workers 的执行结果回调,手动控制队列
- 性能原因: web workers 用于执行耗时的同步计算,运算时间长的话,短期塞入多个消息队列也处理不完,web workers 处理也需要花费时间。(多 Web worker 接收)
- 拆解异步计算,web workers 是一个不错的选择,vs code online 使用 web workers 异步完成代码提示和高亮,web worker 对于这些需要计算的场景提升非常大。
- web workers 消息队列需要根据业务场景设计一个队列消费模型,防止同步计算让 web workers 失去响应。