Webブラウザでのマルチスレッド処理

システム開発

WebブラウザにおけるJavaScriptは、基本的に単一スレッドでタスクを処理します。これはメインスレッドまたはイベントループと呼ばれます。しかし、Web Worker APIを使うことで、並列処理が可能になります。

メインスレッド (イベントループ)

JavaScriptのメインスレッドは、イベントループと呼ばれるメカニズムで動作します。以下の例を見てみましょう。

console.log('Start script...');

setTimeout(() => {
  console.log('Timer fired');
}, 2000);

console.log('End script...');

出力結果:

Start script...
End script...
(2秒後)
Timer fired

スクリプトの実行が開始されると、コンソールに’Start script…’が出力されます。次に setTimeout関数が呼び出されますが、この関数はタイマーをスケジューリングするだけで、2秒後のコールバック関数の実行は保留されます。

その後、コンソールに’End script…’が出力され、メインスレッドのタスクが完了します。2秒後になると、保留されていたコールバック関数が実行され、’Timer fired’が出力されます。

このように、JavaScriptエンジンは単一のメインスレッドで処理を実行しますが、一定の非同期処理はイベントループに登録され、メインスレッドが空いた際に実行されます。

Web Worker

Web Workerを使うと、メインスレッドとは別の並列ワーカースレッドでタスクを実行できます。メインスレッドとWorkerスレッド間ではメッセージングによる通信を行います。

// main.js
const worker = new Worker('worker.js');

worker.onmessage = function(e) {
  console.log('Main received:', e.data);
}

worker.postMessage('Hello Worker!');
console.log('Main script continuing...');
// worker.js
self.onmessage = function(e) {
  console.log('Worker received:', e.data);

  // 重い計算処理
  let counter = 0;
  for (let i = 0; i < 1000000000; i++) {
    counter += i;
  }

  self.postMessage(counter);
}

この例では、メインスレッドからWeb Workerを作成し、メッセージを送信しています。Web Workerはメッセージを受信すると、重い計算処理を実行した後、結果をメインスレッドに返します。

メインスレッドはWeb Workerのメッセージ応答を待つことなく、’Main script continuing…’を出力し、次の処理に進みます。

Web Workerの利点は、メインスレッドをブロックすることなく、CPU負荷の高い処理を実行できることです。一方、Web Workerにはいくつかの制限があり、DOM APIにアクセスできない、ファイルシステムにアクセスできない、新しいWorkerを作成できないなどの点に注意が必要です。

近年では、Web Worker以外にも並列処理を実現する手段がいくつか登場しています。ServiceWorker、WebWorker、WebAssembly、WebGPUなどがあり、用途に応じて使い分ける必要があります。

Webブラウザ上でマルチスレッド処理を適切に利用することで、リッチでインタラクティブなWebアプリケーションを実現できます。

タイトルとURLをコピーしました