Web Worker 是为领会决 JavaScript 在浏览器环境中没有多线程的问题。正常形况下,浏览器执行某段程序的时刻会壅闭直到运行竣事后在恢复到正常状态,而HTML5的Web Worker就是为领会决这个问题,提升程序的执行效率。 以是Web Worker 的最佳使用场景是执行一些开销较大的数据处理或盘算义务。
现在除了IE,其他主流浏览器都已经支持Web Worker。在建立 web worker 之前,我们一样平常需要检测用户的浏览器是否支持它,方式如下:
if(typeof(Worker)!=="undefined"){ //支持 }else{ //浏览器不支持 }
worker是一个工具,通过组织函数Worker建立,参数就是一个js文件的路径;文件中的js代码将运行在主线程之外的worker线程; 建立worker很简朴,如下:
var myWorker = new Worker('worker.js');
注重:worker运行在另一个全局上下文中(self),这个全局上下文不同于window,以是不能在woker中接见window和DOM;
该线程分为两种:dedicated worker和shared worker;dedicated worker只能被初始化它的js上下文中使用;shared worker可以在多个js上下文中使用。通常使用的worker是dedicated worker,它的事情情况可以通过chrome的调试工具查看。
前端开发者应该知道浏览器中JS和UI公用一个线程,JS盘算历程中,不能响应UI;若是遇到盘算量对照大的义务,如操作图像像素时,会造成用户行为得不到响应。Web Worker 是为领会决 JavaScript 在浏览器环境中没有多线程的问题。支持 Web Worker 的浏览器会分外提供一个 JavaScript Runtime 供 Web Worker 使用。它的最佳使用场景是执行一些开销较大的数据处理或盘算义务。
Web Worker 使用起来异常简朴,在“主线程”中执行如下操作即可建立一个 Worker 实例,通过监听 onmessage 事宜获取新闻,通过 postMessage 发送新闻:
“主线程”和Worker 之间通过 postMessage 发送新闻,通过监听 onmessage 事宜来吸收新闻,从而实现二者的通讯。
如下图所示:
焦点代码如下:
//主线程代码 var worker = new Worker('worker.js'); worker.onmessage = function (e) { var data = e.data; } var messageData = { message: 'hello worker!' }; worker.postMessage(messageData);
worker.js 中的代码如下:
self.onmessage = function(e) { var messages = e.data; // e.data为{message: 'hello worker!'} var workerResult = {}; // do something ... postMessage(workerResult); }
使用woker的几个tips
(1)使用若干个worker?
遇到庞大的盘算,需要开启若干worker才合适呢?一样平常的做法是参考navigator.hardwareConcurrency 这个属性,它示意机械支持的并行最大义务数。另有一种动态检测 Worker 数目的方式,有兴趣的话可以看:https://github.com/oftn-oswg/core-estimator。
(2)优化woker与主线程通讯开销
Worker 与“主线程”之间的数据通报默认是通过结构化克隆(Structured Clone)完成的。数据量较大时,克隆历程会对照耗时,这会影响 postMessage 和 onmessage 函数的执行时间。
解决的设施一是先通过 JSON.stringify 将工具序列化,吸收之后再用 JSON.parse 还原。由于:stringfiy + 通报字符串的耗时 < 通报工具的耗时 。
代码如下:
// 操作像素 var imageData = context.createImageData(img.width, img.height); var work = new Worker('./cal.js'); var data = { data: imageData.data, width: imageData.width, height: imageData.height }; // 将通报的参数转换成字符串 work.postMessage(JSON.stringify(data));
另有一种避开克隆传值的方式,就是使用Transferable Objects,主要是接纳二进制的存储方式,接纳地址引用,解决数据交换的实时性问题;Transferable Objects支持的常用数据类型有ArrayBuffer和ImageBitmap;
使用方式如下:
// 操作像素 var imageData = context.createImageData(img.width, img.height); var work = new Worker('./cal.js'); // 转化为类型数组举行通报 var int8s = new Int8Array(imageData.data); var data = { data: int8s, width: imageData.width, height: imageData.height }; // 在postMessage方式的第二个参数中指定transferList work.postMessage(data, [data.data.buffer]);
经测试,使用arrayBuffer之后,通报数据所需的时间为1ms,极大地提高了数据传输的效率。
1.阿里云: 本站现在使用的是阿里云主机,平安/可靠/稳固。点击领取2000米代金券、领会最新阿里云产物的种种优惠流动点击进入
2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各种产物的最新流动,优惠券领取点击进入
3.广告同盟: 整理了现在主流的广告同盟平台,若是你有流量,可以作为参考选择适合你的平台点击进入
链接: http://www.fly63.com/article/detial/998