Hatena::ブログ(Diary)

IT-Walker on hatena このページをアンテナに追加 RSSフィード

2009-07-31 HTML5 Web Workersを超簡単に使えるようにするAlexService0.5を公開

HTML5 Web Workersを超簡単に使えるようにするAlexService0.5を公開しました。

HTML5 Web Workersを超簡単に使えるようにするフレームワークAlexServiceを公開しました。


AlexServiceは、普通のJavaScript関数定義と呼び出しを行うだけで、Web Workersを使用したバックグラウンド処理を行うことができるようになります。試作して使ってみたところ、「これは使える」と言う手応えを得ましたので、機能を追加してテストも割としっかりやり、公開するに至りました。現在のバージョンを0.5としたのは、割と完成度高いよ、と言う気持ちの現れです。


AlexServiceとは何か、を説明する前に、そもそもWeb Workersについてご存じない方も多いと思うので、簡単に説明します。


Web Workersは、JavaScriptバックグラウンド処理を実現するための非常にシンプルで強力なAPIです。

バックグラウンドで動作するスレッド(ワーカスレッド)を簡単に生成できますし、ワーカに対してメッセージを送り、データを共有するのも簡単です(worker.postMessage(msg)でメッセージを送り、ワーカはonmessageハンドラで受け取れます)。


ですが、あまりにシンプル過ぎて、ワーカ同士が様々なコミュニケーションをし合うような、少し高度なアプリケーションを書こうとすると、とたんにコードが複雑になります。

例えばバックグラウンドで動作中のワーカがいるとして、そいつに対して「開始」「一時停止」「停止」などの処理を行いたいとします。そうした場合、メッセージ内に「start」「pause」「stop」のようなメッセージのタイプを埋め込み、ワーカ側ではswitch-caseで処理を分岐する必要が生じます。こうした低レベルの「プロトコル」処理が煩雑で、かなりの労力を強いられます。

また、今述べたのは「UI→ワーカ」と言うメッセージの流れでしたが、バックグラウンドで計算途中に、ユーザに経過を知らせるためにUIを更新したいときなどは、「ワーカ→UI」と言った流れのメッセージ送信を行う必要もあります。つまり、双方向でメッセージが飛び交い、どちらのメッセージ受信処理も長大なswitch-caseになりがちだと言う事です。メッセージ送信処理も、様々な箇所でpostMessage()が記述されることになるのでかなり煩雑です。


それに、ワーカ内ではDOMにアクセスすることができない(window,documentとかに触れない)のもポイントです。ワーカ内はブラウザとは違う空間なので、windowにアクセスしようとしたとたんundefinedであると怒られます。これは結構きつい制限です。なぜならprototype.jsjQueryなど、サードパーティ製のライブラリの中にはwindowオブジェクトを前提にしているものがあるからです。いくら自分たちが、UIと関係しないところではwindowやdocumentにアクセスしないよう気をつけていたとしても、Prototype.jsに依存したコードを一行でも書いているとアウトです(以前はこの問題を、Prototype.jsを書き換える事で乗り切りました・・・)。それに、開発者が複数人いる場合は、「UIと関係しないところではwindowやdocumentにアクセスしないよう気をつけ」るのも限界があります。


なので、素のWeb Workersを使って大きめのアプリを作るのはけっこうしんどいです。

これは前までGearsを使ったハードなAjaxアプリの仕事をしていて、ギリギリまで頑張った結果ワーカの導入をあきらめ、その後応答性の悪さをお客様にひたすら謝り続けた僕が言うんだから、結構信じてもらっていいと思います。


で、AlexServiceですが、HTML5 Web Workersを抽象化し、オブジェクト指向ライクに非同期処理を扱えるようにしたフレームワークです。

AlexServiceを使うと、Web WorkersのAPIを一切知らなくともJavaScriptバックグラウンド処理を手軽に書けるようになります。


AlexServiceは、ワーカ間のコミュニケーションを、シンプルな関数呼び出しで実現できるようにします。

例えば、複雑で時間のかかる計算処理をバックグラウンドで実行するには、以下のようなコードを書くだけです。

new alex.service.Service("calcService", {
  doSuperComplexCalcuration: function() {
    ...超複雑な処理
  }
});

上のメソッドを非同期で呼び出すには、以下のようなコードを記述します。

calcService.doSuperComplexCalcuration(function(result, error) {
  alert("Result is:" + result);
});

このようにAlexServiceを使うと、クラス(サービス)とメソッドを記述するだけで簡単に非同期処理を定義でき、メソッド呼び出しを行うだけで処理を実行できます。低レベルなメッセージングプロトコルを自分で設計/処理する必要がありません。

また、UIと関係のないロジックを全て「サービス」の中にカプセル化でき、UIからはそれを呼び出すだけになります。これにより、ビジネスロジックUIの分離が促進され、ビジネスロジック内からwindowやdocumentに間違ってアクセスしてしまう危険性を減らせます。


バックグラウンド処理を用意に記述できる事は、Webアプリケーションの応答性を劇的に高めることにもつながるだけではなく、UI処理とビジネスロジックの分離を容易にし、Webアプリケーションアーキテクチャを堅牢なものにすることにもつながります。 あなたもAlexServiceを使用して、高速で堅牢なアプリケーションを手軽に作成してみませんか?


もしAlexServiceに興味が湧いたなら、こちらのページからドキュメントを参照できます。

また、オンラインデモはこちら。Web Workersの仕様書に載っている素数計算アプリの改良版で、計算を一時停止/停止することができます。Safari4/Chrome3での閲覧推奨です(Firefox3.5でも動きますが、Firefoxのワーカは少し遅いようです)。


ぜひお試しください!

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。