HTML 速習チュートリアル

HTML Web Workers API

1. Web Worker とは?

Web Worker は、他のスクリプトに影響を与えることなく、バックグラウンドで実行される JavaScript です。

HTML ページでスクリプトを実行すると、スクリプトが終了するまでページは応答しなくなります。一方、Web Worker はバックグラウンドで動作するため、他のスクリプトから独立しており、ページのパフォーマンスに影響を与えません。Web Worker がバックグラウンドで動作している間も、クリックや選択などの操作を通常通り行うことができます。

2. ブラウザのサポート状況

ブラウザにおける Web Worker のサポート状況は以下の通りです。

APIChromeEdgeFirefoxSafariOpera
Web Workers4.0+10.0+3.5+4.0+11.5+

3. Web Worker のサポート確認

Web Worker を作成する前に、ユーザーのブラウザがそれをサポートしているかどうかを確認します。

if (typeof(Worker) !== "undefined") {
  // Web Worker をサポートしている場合の処理
  // Yes! Web Worker を使用できます!
} else {
  // Web Worker をサポートしていない場合の処理
  // Sorry! Web Worker はサポートされていません...
}

4. Web Worker ファイルの作成

まず、外部の JavaScript ファイルに Web Worker 用のコードを記述します。ここでは、数値をカウントアップするスクリプトを作成します。

このスクリプトは "demo_workers.js" という名前で保存します。

// demo_workers.js の内容
var i = 0;

function timedCount() {
  i = i + 1;
  // HTML ページにメッセージを送り返す
  postMessage(i);
  // 500ミリ秒ごとに再実行
  setTimeout("timedCount()", 500);
}

timedCount();

このコードの重要なポイントは postMessage() メソッドです。これは、HTML ページにデータを送信するために使用されます。

5. Web Worker オブジェクトの生成

外部のスクリプトファイルが用意できたら、HTML ページからその Worker を呼び出す必要があります。

以下のコードは、Worker が既に存在するかチェックし、存在しない場合は新しい Web Worker オブジェクトを作成して、"demo_workers.js" 内のコードを実行します。

if (typeof(w) == "undefined") {
  w = new Worker("demo_workers.js");
}

その後、Web Worker からメッセージを受け取るために、onmessageイベントリスナーを設定します。

w.onmessage = function(event) {
  document.getElementById("result").innerHTML = event.data;
};

Web Worker がメッセージを送信すると、onmessage イベント内のコードが実行されます。Web Worker から送信されたデータは event.data に格納されています。

6. Web Worker の終了

Web Worker オブジェクトが作成されると、終了させるまで(外部スクリプトが完了した後でも)メッセージを待ち受け続け、リソースを消費します。

Web Worker を停止させ、ブラウザやコンピュータのリソースを解放するには、terminate() メソッドを使用します。

w.terminate();

7. Web Worker の再利用

Worker 変数を undefined に設定すると、Worker を終了させた後に変数を再利用できるようになります。

w = undefined;

8. Web Worker の完全なサンプルコード

これまでに説明したコードをまとめた、完全な実装例は以下の通りです。

<!DOCTYPE html>
<html>
<body>

<p>カウント: <output id="result"></output></p>
<button onclick="startWorker()">Worker を開始</button> 
<button onclick="stopWorker()">Worker を停止</button>

<script>
var w;

function startWorker() {
  if (typeof(Worker) !== "undefined") {
    if (typeof(w) == "undefined") {
      w = new Worker("demo_workers.js");
    }
    w.onmessage = function(event) {
      document.getElementById("result").innerHTML = event.data;
    };
  } else {
    document.getElementById("result").innerHTML = "お使いのブラウザは Web Worker をサポートしていません。";
  }
}

function stopWorker() { 
  w.terminate();
  w = undefined;
}
</script>

</body>
</html>

9. Web Worker と DOM

Web Worker は外部ファイルで実行されるため、以下の JavaScript オブジェクトにはアクセスできません。

  • window オブジェクト
  • document オブジェクト
  • parent オブジェクト