1. 简单使用
- 介绍
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。
在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。
-
Web Worker简单使用
Web Worker示例
//main.js
const first = document.querySelector('#number1');
const second = document.querySelector('#number2');
const result = document.querySelector('.result');
if (window.Worker) {
const myWorker = new Worker("worker.js");
first.onchange = function() {
myWorker.postMessage([first.value, second.value]);
}
second.onchange = function() {
myWorker.postMessage([first.value, second.value]);
}
myWorker.onmessage = function(e) {
result.textContent = e.data;
}
myWorker.onerror = function (e) {
console.log(['ERROR: ', e.lineno, ' in ', e.filename, ': ', e.message].join(''));
};
}
//worker.js
onmessage = function(e) {
const result = e.data[0] * e.data[1];
if (isNaN(result)) {
postMessage('Please write two numbers');
} else {
const workerResult = 'Result: ' + result;
postMessage(workerResult);
}
}
-
Web Worker使用限制
(1) 同源限制
分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
(2) DOM 限制
Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
(3) 通信联系
Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。
(4) 脚本限制
Worker线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest对象发出AJAX请求。
(5) 文件限制
Worker线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
-
Worker 线程一旦新建成功,就会始终运行,比较耗费资源。使用完毕必须关闭。
(1) 主线程终止worker
myWorker.terminate();
(2) worker线程终止worker
close();
- 数据通信
主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。
Structured Clone 是 postMessage 默认的通信方式。这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。
主线程与 Worker 也可以交换二进制数据,比如 File、Blob、ArrayBuffer 等类型。
- 兼容性
主流浏览器在几年前就支持Worker。
2. Web Worker 文献综述
-
web worker和setTimeout / Promise.all区别
JS 单线程中的“并发”通过Event Loop实现不同Task的上下文切换 (Context Switch)。这些 Task 通过 BOM API 调起其他线程为主线程工作, 但回调函数代码逻辑依然由 JS 串行运行。
Web Worker 是 JS 多线程运行技术。
- 拆分同步逻辑的异步方案
将同步任务拆分为多个小于 16ms 的子任务, 然后在页面每一帧前通过 requestAnimationFrame 按计划执行一个子任务, 直到全部子任务执行完毕。
拆分同步逻辑存在以下几个问题:
(1) 不是所有 js 逻辑都可拆分
比如数组排序, 树的递归查找, 图像处理算法等。
(2) 可以拆分的逻辑难以把控粒度
拆分的子任务在高性能机器上可以控制在16ms内, 但在性能落后机器 上就超过了。
- 性能提升
(1) 多线程与CPU核数
Worker多线程并不会直接带来计算性能的提升, 能否提升与设备CPU核数和线程策略有关。真正带来性能提升的是多核多线程并发。
(2) 通信速度
提升的性能 = 并行提升的性能 – 通信消耗的性能
- 数据传输方式
(1) Structured Clone
Structured Clone 是 postMessage 默认的通信方式。复制一份线程 A 的 JS Object内存给到线程 B, 线程B能获取和操作新复制的内存。
简单有效地隔离不同线程内存, 避免冲突。但Object规模过大时, 会占用大量的线程时间。
兼容性:较好
(2) Transfer Memory
线程A将指定内存的所有权和操作权转给线程B, 转让后线程A无法再访问这块内存。
Transfer Memory以失去控制权来换取高效传输, 通过内存独占给多线程并发加锁。
兼容性:IE11+
(3) Shared Array Buffer
Shared Array Buffer 是共享内存, 线程A和线程B可以同时访问和操作同一块内存空间,数据共享。
多个并行的线程共享内存,会产生竞争问题,不像前 2 种传输方式默认加锁。
兼容性:只有Chrome 68+支持.
-
Web Worker适用场景
(1) 2010 年, The Basics of Web Workers
数据处理、文本处理、图像/视频处理、网络处理
(2) 2018 年, Parallel programming in JavaScript using Web Workers
Canvas drawing(离屏渲染方面)、Virtual DOM diffing(前端框架方面)、indexedDB(本地存储方面)、Webassembly(编译型语言方面)
参考资料
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。