Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[译]WebWorker到底有多快 #1

Open
joeyguo opened this issue May 13, 2016 · 1 comment
Open

[译]WebWorker到底有多快 #1

joeyguo opened this issue May 13, 2016 · 1 comment

Comments

@joeyguo
Copy link
Owner

joeyguo commented May 13, 2016

来源:How fast are web workers?

       

下一版本的 Firefox OS 移动操作系统将通过使用其多核处理器来充分利用设备的性能,JavaScript虽然在单线程上执行,但通过使用web workers可以实现代码的并行执行,这样将释放浏览器中任何可能阻塞主线程的程序,UI动画也将因此更顺畅的执行。

web workers 简介

有几种类型的web workers:

他们各自拥有不同特性,但有着相似的设计形式,worker中代码将在自己开辟的独立线程上执行,与主线程及其他worker并行执行,不同类型的workers维护着一个共同的接口。

web workers

专用的web workers将在主线程上被实例化,并且其他worker将只能通过它来进行通信

Shared workers

Shared workers 允许同源中的所有页面或脚本(包含不同的浏览器标签, iframes或者其他 shared workers)之间进行通信.

Service workers

近期,Service workers 得到了大量的关注,他可以作为web代理服务器(开发者能够对页面请求进行控制)将内容传递给请求者(如主线程)。不仅如此,它还能够支持离线应用。Service workers是一个非常新的API,现在仍没有兼容所有的浏览器,本文将不对其详细介绍。

为了验证web workers让Firefox OS运行得更快,我们通过对其进行基准测试来验证他的速度。

创建web workers的开销

本文主要针对Firefox OS。所有的数据都在Flame手机上所测量。
第一组测试是创建 web workers所花费的时间,为此,我们创建一个script文件,该script文件实例化了一个web worker并发送一个最小的消息。发现web worker快速对其回复。当主线程接收到响应后,我们将得到这个过程所花费的时间。
然后销毁web worker并对上面所述的实验进行多次重复操作,我们将能够得到创建web worker所花费的平均时间,可以通过如下代码简单地实例化一个web worker

// Start a worker.
var worker = new Worker('worker-script.js');

// Terminate a worker.
worker.terminate();

同样的方式来创建广播通道

// Open a broadcast channel.
var channel = new window.BroadcastChannel('channel-name');

// Close a broadcast channel.
channel.close();

Shared workers 无法在这里进行基准测试,因为他们一旦被创建,开发者将不能够销毁他们,它们将由浏览器接管。鉴于此,我们不能通过创建和销毁
Shared workers来得到有意义的基准测试。

Web workers大约使用40毫秒被实例化。这个时间相当稳定的,波动只有几毫秒。创建一个broadcast channel 通常是在1毫秒内完成。

正常情况下,浏览器的刷新频率为60帧/秒(fps),这意味着没有JavaScript代码运行应该超过一帧所需时间,即16.66毫秒(60帧/秒)。否则页面的渲染就会出现卡顿效果,也就是常说的jankiness。

实例化web workers非常高效的,但是仍可能不适合单帧所用的时间。这就是为什么要创造尽可能少的web workers并且重用它们的重要原因。

消息延迟

web workers的关键之一,是它能够在主线程及workers之间进行快速通信,以下列出主线程与web worker之间两种不同的通信方式。

postMessage

这个API是默认及首选的,用来web worker发送和接收消息。如下:

// Send a message to the worker.
worker.postMessage(myMessage);

// Listen to messages from the worker.
worker.onmessage = evt => {
  var message = evt.data;
};

Broadcast Channel

这是一个新的API,现在只能在Firefox中使用。Broadcast Channel能够所有同源的上下文进行广播消息。包含同源的页面,iframes,或workers都能够发送和接收消息:

// Send a message to the broadcast channel.
channel.postMessage(myMessage);

// Listen to messages from the broadcast channel.
channel.onmessage = evt => {
  var message = evt.data;
};

这里的基准测试,我们使用类似于上述代码,不同之处在于web worker将不被销毁,并在每一个操作都重复使用它。所以,得到的往返响应时间应除以2。
可能你已想到,简单的postMessage是很快的,它通常只需要在0至1毫秒来发送一个消息,不管是对一个web还是shared worker。Broadcast channel的API大约需要1至2毫秒。

在正常情况下,workers之间通信很快,你不需要担心这里的通信速度,当然,发送更大的消息将会使用较长的时间。

消息的大小

有两种形式能够给web workers发送消息

  • Copying the message
  • Transferring the message

在第一种情况下,该消息将被序列化,复制然后发送。在后者,数据将被传送,这意味着消息发送出去后,发送者将不再使用它。数据传送几乎是瞬时的,所以不能基准测试。然而,只有ArrayBuffer是可传送的。

正如预期,序列化、复制和反序列化数据对消息传输增加了显著的开销。消息越大,时间越长。

在这个基准测试中,我们发送一个 typed array 给 web worker。 它的大小在每个迭代中逐步增加。传送消息的大小跟传输时间呈线性相关。对于每次测量,我们可以把数据大小(kb)除以时间(ms)来得到传输速度(kb/ms)。

通常,在Flame手机中,postMessage的传输速度在80 kB/ms,而broadcast channel则为12kB/ms,这意味着,如果你想你的消息适应单个帧,那么当使用postMessage时,让消息的大小保持在1300kB内;在使用broadcast channel时,使其大小小于200kB。否则,可能会出现丢帧的情况。

在这个基准测试中,我们使用typed array,因为它使我们能够以千字节为单位确定其大小。你也可以传输JavaScript对象,但由于序列化的过程,他们需要更长的时间去发送。对于小的对象,这其实并不重要,但如果你需要发送巨大的对象,你不妨将其序列化成二进制格式。并且使用类似于协议缓冲区的方式。

正常使用下Web workers相当快

以下是在Flame 手机中对web workers的各种基准测试的总结:

操作 ->

  • 实例化一个web worker -》 40 ms
  • 实例化一个broadcast channel -》 1 ms
  • postMessage 的通信延迟 -》 0.5 ms
  • broadcast channel的通信延迟 -》 1.5 ms
  • postMessage的通信速度 -》 80 kB/ms
  • broadcast channel的通信速度 -》 12 kB/ms
  • postMessage的最大传输数据大小 -》 1,300 kB
  • broadcast channel的最大传输数据大小 -》 200 kB

基准测试用来确保你所使用的解决方案是非常快的。这个过程将大量的猜测从web开发中消除。

@joeyguo joeyguo changed the title web workers [译]WebWorker到底有多快 May 13, 2016
@a2htray
Copy link

a2htray commented Mar 21, 2017

拿issue还写博客吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants