Mapion マピオンラボ Javascript Web Workersを使いJavaScriptでバックグラウンド処理に挑む
JavaScriptでバックグラウンド処理が可能になるWeb Workersを試してみました。
以下のようにWorker用のJSファイルを別に作り、それをスクリプト中で呼び出すことで利用します。
index.html
var worker = new Worker("test-worker.js");
// workerにデータをPOST
worker.postMessage("働け");
// worker.jsからpostされた場合のハンドリング
worker.onmessage = function(event) {
// 返り値はevent.dataに含まれます
alert(event.data); // => "働きました"
}
test-worker.js
onmessage = function(event) {
var res = "";
// POSTされたデータは event.data に含まれる
var data = event.data; // => "働け"
if (data == "働け") {
res = "働きました";
} else {
res = "今日は休みます";
}
postMessage(res); // メッセージを返します
}
渡せるデータに制約がある。
index.html も test-worker.js も postMessage でデータをやり取りします。
問題はこの渡すデータ形式に制限があり、Firefox だと文字列、配列、オブジェクトを渡せますが、Safari と Chrome は文字列しか渡せません。
※Chrome は gears の WorkerPool API の方を利用することで、配列やオブジェクトも渡せるっぽいです。
とりあえず、Web Workers の可能性を探るという意味で、ここから先は Firefox でテストします。
大量データの解析に使ってみた
試験内容:
friendfeed から「ニュース」文字列で検索した結果1万件のデータを Ngram で解析し、全文検索用の転置インデックスを作成してみる。
JSONリクエストのコストと区別するため、インデックス開始前にアラートで一旦停止、メモリ使用量が一度下がってから解析を始める。
結果:速度、メモリ使用量はほとんど変化しなかった。
相違点: アラートのOKを押した後、通常の解析では一瞬ブラウザが固まる。Web Workers を利用するとスムーズにブラウザが動作した。試しに解析対象の量を3倍に増やしても問題なく動作したことも確認。
結論:処理負荷を上げても Web Workers を使えば、ユーザーインタラクションに影響を与えない!
その他のポイント
- importScripts を使えば外部JSの読み込みが可能
- Worker 内で別の Worker を生成することも可能
- XHR を利用できる
- setTimeout や setInterval が使える
- Worker 自身に値を保持することもできる
難点
- Worker 中のデバッグは難しそうです。DOM操作できないし、console も使えない。
- DOM処理を行えないからJSONPが出来ない。コールバック後の処理なら可能。
- Firefox でアプリを作ると、Safari と Chrome で爆死する可能性(渡せるデータ形式の問題で)。
課題
課題としては「使い方はわかったけど、使いどころがまだわからない」ということが言えます。 試行錯誤を繰り返して、ノウハウを少しずつ蓄積していく必要がありそうです。
※2010/05/31 変更
コメント指摘によりサンプルソースコードを修正させていただきました。
var で指定した変数 data を if のチェックするときに二重引用符で囲っていました。動かないサンプルコードを掲載してしまい、申し訳ありませんでした。




