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年以上放置されているようですが、、

参考

onloadの扱い

Chromeでのみ確認しましたがちょっとイレギュラーな動作となりました。

  • WebWorker
    onloadのタイミングをJavascript側で意識する必要はありません。Worker起動時の処理中にpostMessageすると、処理が終わってからmessageイベントが発生します。
  • WebMessaging(iframe)
    $iframe.onload後でないと、postMessageが拾われません。
  • WebMessaging(window)
    window.onload後でないと、postMessageが拾われません。

コンソール出力

Workerプロセス内ではconsole.log()などのデバッグ用の関数が使えません。なんだかんだでこれが開発する上で一番大きな違いな気もします。