Html5-web-workers

提供:Dev Guides
移動先:案内検索

HTML5-Web Workers

JavaScriptはシングルスレッド環境で実行するように設計されています。つまり、複数のスクリプトを同時に実行することはできません。 UIイベントを処理し、大量のAPIデータを照会および処理し、DOMを操作する必要がある状況を考えてください。

JavaScriptは、CPU使用率が高い状況でブラウザーをハングさせます。 JavaScriptが大きなループを通過する簡単な例を見てみましょう-

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>

      <script>
         function bigLoop() {

            for (var i = 0; i <= 10000; i += 1) {
               var j = i;
            }
            alert("Completed " + j + "iterations" );
         }

         function sayHello(){
            alert("Hello sir...." );
         }
      </script>

   </head>

   <body>
      <input type = "button" onclick = "bigLoop();" value = "Big Loop"/>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

それは次の結果を生成します-

Big Loopボタンをクリックすると、Firefoxで次の結果が表示されます-

ビッグループ

Web Workersとは何ですか?

上記で説明した状況は、ユーザーインターフェイスを中断せずに、通常は別々のスレッドで実行される、計算負荷の高いタスクをすべて実行する Web Workers を使用して処理できます。

Web Workersは、クリックやその他のユーザーインタラクションに応答するスクリプトによって中断されない長時間実行スクリプトを許可し、ページの応答性を維持することなく、長いタスクを実行できます。

Web Workersはバックグラウンドスクリプトであり、比較的重いため、大量に使用することを意図していません。 たとえば、4メガピクセルの画像の各ピクセルに対して1つのワーカーを起動することは不適切です。

スクリプトがWebワーカー内で実行されている場合、Webページのウィンドウオブジェクト(window.document)にアクセスできません。つまり、WebワーカーはWebページおよびDOM APIに直接アクセスできません。 Web WorkersはブラウザーUIをブロックできませんが、それでもCPUサイクルを消費し、システムの応答性を低下させる可能性があります。

Web Workersの仕組み

Web Workersは、ワーカーが実行するコードを含むJavaScriptファイルのURLで初期化されます。 このコードはイベントリスナーを設定し、メインページからイベントリスナーを生成したスクリプトと通信します。 以下は、単純な構文です-

var worker = new Worker('bigLoop.js');

指定されたjavascriptファイルが存在する場合、ブラウザは非同期にダウンロードされる新しいワーカースレッドを生成します。 ワーカーへのパスが404エラーを返す場合、ワーカーはサイレントに失敗します。

アプリケーションに複数のサポートJavaScriptファイルがある場合は、次のようにコンマで区切られた引数としてファイル名を取る* importScripts()*メソッドをインポートできます-

importScripts("helper.js", "anotherHelper.js");

Web Workerが生成されると、* postMessage()*メソッドを使用してWeb Workerとその親ページ間の通信が行われます。 ブラウザ/バージョンに応じて、postMessage()は単一の引数として文字列またはJSONオブジェクトを受け入れることができます。

Web Workerから渡されたメッセージは、メインページの onmessage イベントを使用してアクセスされます。 次に、Web Workerを使用してbigLoopの例を作成しましょう。 以下は、ループを実行して変数の最終値を返すWebワーカーを生成するメインページ(hello)です* j *-

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>

      <script>
         var worker = new Worker('bigLoop.js');

         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };

         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>

   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

以下は、bigLoop.jsファイルの内容です。 これは、* postMessage()* APIを使用して通信をメインページに戻します-

for (var i = 0; i <= 1000000000; i += 1) {
   var j = i;
}
postMessage(j);

これは、次の結果を生成します-

Web Workersを停止する

Web Workersはそれ自体では停止しませんが、それらを開始したページは* terminate()*メソッドを呼び出すことで停止できます。

worker.terminate();

終了したWeb Workerは、メッセージに応答したり、追加の計算を実行したりしなくなります。 ワーカーを再起動することはできません。代わりに、同じURLを使用して新しいワーカーを作成できます。

エラー処理

以下は、エラーをコンソールに記録するWeb Worker JavaScriptファイルのエラー処理関数の例を示しています。 エラー処理コードでは、上記の例は次のようになります-

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>

      <script>
         var worker = new Worker('bigLoop.js');

         worker.onmessage = function (event) {
            alert("Completed " + event.data + "iterations" );
         };

         worker.onerror = function (event) {
            console.log(event.message, event);
         };

         function sayHello() {
            alert("Hello sir...." );
         }
      </script>
   </head>

   <body>
      <input type = "button" onclick = "sayHello();" value = "Say Hello"/>
   </body>
</html>

ブラウザサポートの確認

以下は、ブラウザで利用可能なWeb Worker機能のサポートを検出するための構文です-

<!DOCTYPE HTML>

<html>
   <head>
      <title>Big for loop</title>
      <script src = "/js/modernizr-1.5.min.js"></script>

      <script>
      function myFunction() {

         if (Modernizr.webworkers) {
            alert("Congratulation!! you have web workers support." );
         } else {
            alert("Sorry!! you do not have web workers support." );
         }
      }
      </script>
   </head>

   <body>
      <button onclick = "myFunction()">Click me</button>
   </body>
</html>

これは、次の結果を生成します-