MENU

Web Workers — メインスレッドを止めない並列JavaScript実行API

Web Workers アイキャッチ
Web Workers

Web Workersは、ブラウザ上のJavaScriptをメインスレッドとは別のバックグラウンドスレッドで実行するためのW3C仕様です。2009年4月にW3Cが最初のワーキングドラフトを公開し、その後WHATWG HTML Living Standardに統合されて今日まで進化を続けています。従来のJavaScriptはUIイベント・描画・スクリプトすべてが単一スレッドに混在していたため、重い計算が走るとボタンクリックすら受け付けないフリーズが発生していました。Web Workersはこの問題を解決し、ブラウザにマルチスレッドの世界を持ち込んだ重要なAPIです。

目次

この記事の目次

  1. 三種類のワーカーと役割
  2. メインスレッドとの通信モデル
  3. 実用される代表的なシーン
  4. 制約と他の並列手段との比較
  5. まとめ

三種類のワーカーと役割

三種類のワーカーと役割

Web Workersには大きく三種類のバリエーションがあります。最も基本的なのは「Dedicated Worker」で、生成元のページに1対1で紐づき、new Worker('worker.js') の一行で起動します。親と子は postMessageonmessage ハンドラだけで通信し、相互にDOMやwindowオブジェクトにはアクセスできません。これは設計上の制約で、競合状態を生まないための明確な切り分けになっています。1つのページ内で複数のワーカーを並列に動かすことで、画像処理・暗号化・物理シミュレーションといったCPUバウンドな処理をUIから完全に隔離できます。

「Shared Worker」は同一オリジンの複数タブやiframeから接続できる共有型で、WebSocket接続のプールや状態の同期に便利です。「Service Worker」は2014年に追加されたより高機能なワーカーで、ネットワークリクエストを横取りしてキャッシュを返したり、プッシュ通知を受け取ったりとPWAの根幹を担います。これらは同じ「ワーカー」の枠組みですが、ライフサイクルと権限が異なり、用途に応じて使い分ける設計です。

メインスレッドとの通信モデル

メインスレッドとの通信モデル

ワーカーとの通信は構造化複製アルゴリズム(structured clone)によるオブジェクトのコピーで行われます。数値・文字列・配列・Map・Setなど多くの型をそのまま渡せますが、関数やDOMノードは渡せません。大きなArrayBufferをコピーすると性能が出ないため、所有権を移譲する「Transferable Objects」が用意されており、postMessage(buffer, [buffer]) の形で渡せばゼロコピー転送になります。WebGLのテクスチャ生成や音声処理のように大量のバイナリを扱うケースで威力を発揮します。

2017年にはさらに進んだ並列モデルとしてSharedArrayBufferとAtomicsが標準化され、ワーカー間で同じメモリを共有できるようになりました。SpectreおよびMeltdown脆弱性の影響で一時無効化されましたが、Cross-Origin-Opener-PolicyとCross-Origin-Embedder-Policyの二つのヘッダで「クロスオリジン分離」状態を作ることが条件で再び有効化されています。Wasmと組み合わせれば、ブラウザ上でほぼネイティブ相当のマルチスレッド処理が可能です。

実用される代表的なシーン

実用される代表的なシーン

実務でWeb Workersが選ばれる典型例は、リアルタイムMarkdownエディタの構文解析やコードハイライト処理です。数千行のドキュメントを毎キーストロークで再解析するとメインスレッドではタイピングが追いつかなくなりますが、ワーカーに逃がせばUIは滑らかなまま結果だけが少し遅れて反映される快適な体験になります。FigmaのようなブラウザGUIアプリでも重要なレイアウト計算をワーカーに切り出して滑らかな描画を維持しています。

もう一つの定番は画像処理です。スマートフォンで撮影された高解像度写真をアップロード前にブラウザでリサイズ・回転・WebP圧縮するケースで、メインスレッドで処理すると数秒のフリーズが発生してしまいます。OffscreenCanvas API(2018年〜)と組み合わせるとCanvasの描画自体もワーカー側で完結し、メインスレッドは描画結果を画面に流すだけ、という設計が可能になりました。Wasmで書かれた重い計算ライブラリも、ワーカーから呼ぶのが定石です。

制約と他の並列手段との比較

制約と他の並列手段との比較

Web Workersには明確な制約もあります。最大の制約はDOM・window・documentに一切触れない点で、UIに反映するには必ずメインスレッドへメッセージを送る必要があります。また起動にはワーカーごとにJavaScriptランタイムを別途立ち上げるコストがかかるため、ミリ秒単位で頻繁に作って捨てるのは向きません。プールとして使い回すか、Webアプリ起動時に一度だけ生成する設計が標準です。デバッグもメインスレッドとは別のコンテキストになるため、Chrome DevToolsの「Threads」ペインを使います。

並列処理にはWeb Workers以外にもAudioWorklet(音声処理専用、2018年〜)やPaintWorklet・LayoutWorklet(CSS拡張、Houdini系)といった派生APIが存在します。ただしこれらは特定の用途に特化したもので、汎用的なバックグラウンド処理にはWeb Workersが第一選択です。Node.jsのworker_threadsもWeb Workersと似たAPIで設計されており、サーバーサイドJSとフロントを行き来する開発者にとっては学習コストが低い並列モデルです。

まとめ

Web Workersは、シングルスレッドだったJavaScriptに本格的な並列処理を持ち込んだWebプラットフォームの基盤APIです。OffscreenCanvas・Wasm・SharedArrayBufferと組み合わせればブラウザ上でデスクトップアプリ並みの計算と滑らかな描画を両立でき、重い処理を抱えるWebアプリ開発における必須の道具と言えます。

※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次