WebWorkerとWebMessagingの比較
WebWorkerのプロセス間通信とWebMessagingは使い方が似ていて混同するので違いをまとめました。WebMessagingについてはiframeとwindow.open()とで挙動が違う箇所があったので分けて比較しています。
API比較
引数は以下のように定義しているとします。
- $iframe = document.createElement(“iframe”);
- $worker = new Worker(“worker.js”);
- e: addEventListener("message", func, false) におけるfuncの引数
WebWorker | WebMessaging | |
親がlisten | $worker.addEventListener(“message”, func, false); | window.addEventListener(“message”, func, false); |
親からpostMessage | $worker.postMessage(data); | $iframe.contentWindow.postMessage(data, origin); |
子がlisten | self.addEventListener(“message”, func, false); | window.addEventListener(“message”, func, false); |
子からpostMessage | self.postMessage(data); | e.source.postMessage(data, origin); (iframeの場合は以下同等) window.parent.postMessage(data, origin); |
selfはWorker内でのルートオブジェクトです。
ベンチマーク
以下の処理におけるパフォーマンスを比較しました。
- 軽い処理を10000回
- 重い処理を1回
http://www.asanoboylab.net/workervsiframe/
手元のChromeで確認するとこのようになりました。
Web Worker | Web Messaging(iframe) | Web Messaging(window) | |
10000 light tasks | 1093msec | 1553msec | 1480msec |
1 heavy task | 395msec | 406msec | 387msec |
やはり通信のオーバーヘッドはWebWorkerの方が最適化されていますね。
SubWorkerについて
他のブラウザでは未確認ですが、ChromeではWorker内でWorkerを作る事が出来ません。実は今回はこの現象のためiframeをWebWorker代わりに使おうとして両者の比較を行う事になりました。仕様上はSubWorkerを作成する事が出来るようですので、今後に期待ですね。2年以上放置されているようですが、、
参考
- http://www.html5rocks.com/ja/tutorials/workers/basics/#toc-enviornment-subworkers
- https://developer.mozilla.org/ja/docs/DOM/Using_web_workers#Subworker_.E3.81.AE.E7.94.9F.E6.88.90
onloadの扱い
Chromeでのみ確認しましたがちょっとイレギュラーな動作となりました。
- WebWorker
onloadのタイミングをJavascript側で意識する必要はありません。Worker起動時の処理中にpostMessageすると、処理が終わってからmessageイベントが発生します。 - WebMessaging(iframe)
$iframe.onload後でないと、postMessageが拾われません。 - WebMessaging(window)
window.onload後でないと、postMessageが拾われません。
コンソール出力
Workerプロセス内ではconsole.log()などのデバッグ用の関数が使えません。なんだかんだでこれが開発する上で一番大きな違いな気もします。