LoginSignup
30
23

More than 5 years have passed since last update.

WebWorkerで並列処理

Posted at

どうせ疑似的に並列処理するだけかと思ったら、本当にできたので一応メモ。

やったこと

入力した内容をリアルタイムにDeflate形式で圧縮しつつ、確認用に復元されたデータも表示する処理。

  • Defalteへの圧縮処理は js-deflate を使用
  • 画面表示には Sencha Touch を使用

js-deflateによる圧縮・伸張処理を並列で走らせておき、入力内容に変更があればリアルタイムに圧縮・伸張してそれぞれ表示している。

cap01.png

長い文字列を入力しても重くならず、圧縮・伸張処理によって画面が固まらないことまでは確認した。

実装

並列で走らせておくコードを別ファイルに記述し、メッセージを介してやり取りする仕組み。

ウェブ ワーカーの基本 - HTML5 Rocks
http://www.html5rocks.com/ja/tutorials/workers/basics/

別ファイルにせずともBlobを使用すればインラインで記述可能だが、BLob対応していないブラウザで動かなかったので試していない。

メインスクリプト

ここではworker.jsが並列処理されるコードとして、Workerの引数に指定している。

メインスクリプト.js
wkCompression = new Worker('worker.js');
// メッセージを受け取った際の処理を定義
wkCompression.onmessage = function(message) {
    var data = message.data;
    // 処理結果を受けて振り分け
    switch (data.event) {
        case 'start':
            break;
        case 'compressed':
            // 圧縮されたデータの表示
            outcon.setValue(data.data);
            break;
        case 'complete':
            // 伸張されたデータの表示
            outdecon.setValue(data.data);
            break;
    }
};

メッセージをポスト

キー入力があるタイミングで、入力内容をWorker(worker.js)にポストしてやる。

メインスクリプト.js
    onKeyupInput: function(src) {
        var val = src.getValue();
        wkCompression.postMessage({data: val});
    }

woker.js

このファイルが別スレッドで実行される。
それゆえ以下の要素にはアクセスできないようです。

  • DOM(非スレッドセーフ)
  • window オブジェクト
  • document オブジェクト
  • parent オブジェクト

ただしimportScriptsを使用すると外部スクリプトを読み込むことはできるので、
今回はこれを利用してjs-deflateを読み込んでいます。

worker.js
// キー入力のたびに呼ばれることになる
onmessage = function(message) {
    this.importScripts('./lib/rawdeflate.js');
    this.importScripts('./lib/rawinflate.js');
    this.importScripts('./lib/base64.js');

    // 開始を伝える
    this.postMessage({event: 'start'});

    // 圧縮結果をメッセージ送信(ついでにBase64変換)
    var result = result = Base64.toBase64(RawDeflate.deflate(str));
    this.postMessage({
        event: 'compressed',
        data: result
    });

    // 伸張結果をメッセージ送信
    result = RawDeflate.inflate(Base64.fromBase64(result));
    this.postMessage({
        event: 'complete',
        data: result
    });
}

ちなみにこの場合、importScriptsは実行のたび読み込まれるので注意。

Ext.ux.WebWorker

ExtJS または Sencha Touchでやる場合は、
プラグインが公開されているのでそちらを利用すればそれなりにきれいに書けます。

Ext.ux.WebWorker Sencha Tool: Other, Plugins — Sencha Market

30
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
23