什么是woker

官方的解释是这样的:

worker是一个对象,通过构造函数Worker创建,参数就是一个js文件的路径;文件中的js代码将运行在主线程之外的worker线程;

var jsFileURI = JS_FILE_PATH;  // js文件路径

var worker = new Worker(jsFileURI);

worker运行在另一个全局上下文中(self),这个全局上下文不同于window,所以不能在woker中访问window和DOM;

该线程分为两种:dedicated workershared worker;dedicated worker只能被初始化它的js上下文中使用;shared worker可以在多个js上下文中使用。通常使用的worker是dedicated worker,它的工作情况可以通过chrome的调试工具查看。

为什么引入woker?

前端开发者应该知道浏览器中JS和UI公用一个线程,JS计算过程中,不能响应UI;如果遇到计算量比较大的任务,如操作图像像素时,会造成用户行为得不到响应。Web Worker 是为了解决 JavaScript 在浏览器环境中没有多线程的问题。支持 Web Worker 的浏览器会额外提供一个 JavaScript Runtime 供 Web Worker 使用。它的最佳使用场景是执行一些开销较大的数据处理或计算任务。

woker是怎么工作的?

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与主线程通信开销

该段主要参考百度地图技术博客(https://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MzIzNDE0NjMzOQ==#wechat_webview_type=1&wechat_redirect)。

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,极大地提高了数据传输的效率。

web worker 扫盲篇的更多相关文章

  1. Web Worker javascript多线程编程(二)

    Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...

  2. 深入HTML5 Web Worker应用实践:多线程编程

    HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能.它不但强化了 Web 系统或网页的表现性能 ...

  3. 深入 HTML5 Web Worker 应用实践:多线程编程

    深入 HTML5 Web Worker 应用实践:多线程编程 HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越 ...

  4. 分布式协调服务Zookeeper扫盲篇

    分布式协调服务Zookeeper扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 身为运维工程师对kubernetes(k8s)可能比较熟,那么etcd(go语言实现)分布式协 ...

  5. HTTP/2协议–特性扫盲篇

    HTTP/2协议–特性扫盲篇 随着web技术的飞速发展,1999年制定的HTTP 1.1已经无法满足大家对性能的要求,Google推出协议SPDY,旨在解决HTTP 1.1中广为人知的性能问题.SPD ...

  6. web worker 的传值方式以及耗时对比

    背景 前一阵子开发的项目 pptx 导入, 由于自己的代码问题,引起了个性能问题,一个 40p 的 pptx 文件,转换成 json 数据,大概要耗时 60s+ ,虽然后面发现是某个使用频率非常高的函 ...

  7. 文档通信(跨域-不跨域)、时时通信(websocket)、离线存储(applicationCache)、开启多线程(web worker)

    一.文档间的通信 postMessage对象 //不跨域 1.iframe:obj.contentWindow [iframe中的window对象] iframe拿到父级页面的window: pare ...

  8. html5 web worker学习笔记(记一)

    (吐槽:浏览器js终于进入多线程时代!) 以前利用setTimeout.setInterval等方式的多线程,是伪多线程,本质上是一种在单线程中进行队列执行的方式.自从html5 web worker ...

  9. Httpd服务入门知识-http协议版本,工作机制及http服务器应用扫盲篇

    Httpd服务入门知识-http协议版本,工作机制及http服务器应用扫盲篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Internet与中国 Internet最早来源于美 ...

随机推荐

  1. iOS 从url中获取文件名以及后缀

    //这里有一个模拟器沙盒路径(完整路径) NSString* index=@"/Users/junzoo/Library/Application Support/iPhone Simulat ...

  2. angularjs实现首页轮播图

    <!DOCTYPE html> <html ng-app="myApp" lang="en"> <head> <met ...

  3. maven私服搭建nexus/windows/linux(一)

    为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,还有就是公司内部开发的一些版本的jar包,如果没有私服需要一人拷贝一份然后再自己安 ...

  4. NPOI操作类

    using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Secu ...

  5. Sql日期时间格式转换大全

    简介:我们经常会用到sql日期转换,这里列出了日期输出为字符串的所有代码 输出格式 2014-06-12 ), ) 输出格式 2014-06-12 22:31:18 ), ) 以下是各种转换日期代码号 ...

  6. ubuntu12.04.5安装openssh-server所引发的血案

    刚安装好的ubuntu12.04.5在安装openssh-server之后,安装其他软件都安装不了,如下: root@ubuntu:/home/lancer/software/ssh# apt-get ...

  7. C#小知识点记录(QQ交流群的一个小问题)Linq提取数据

    请教 这里 LINQ想 找到 最后的 4条 记录 然后放在 这里这个 List Linq查找怎么写呀? 解答:写了一个小例子作为解答. namespace C_Sharp { class Progra ...

  8. netty——私有协议栈开发案例

    netty--私有协议栈开发案例 摘要: 在学习李林峰老师的Netty权威指南中,觉得第十二章<私有协议栈开发>中的案例代码比较有代表性,讲的也不错,但是代码中个人认为有些简单的错误,个人 ...

  9. LeanCloud 调研报告

    LeanCloud 是一家做后端即服务(BaaS)的厂商,目标是让移动互联网开发者能更加方便的开发应用. 出于工作关系,对 leancloud 进行了一番调研:主要目标是学习其后端即服务的产品化思路等 ...

  10. javaEE-string家族三大流氓

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...