ウェブワーカーとサービス ワーカーがサイトのパフォーマンスを向上させる仕組みと、ウェブワーカーとサービス ワーカーの使い分け。
この概要では、ウェブワーカーとサービス ワーカーがウェブサイトのパフォーマンスを向上させる仕組みと、ウェブワーカーとサービス ワーカーの使い分けについて説明します。ウィンドウと Service Worker の通信の具体的なパターンについては、このシリーズの残りの部分をご覧ください。
ワーカーがウェブサイトを改善する方法
ブラウザは、単一のスレッド(メインスレッド)を使用して、ウェブページ内のすべての JavaScript を実行し、ページのレンダリングやガベージ コレクションの実行などのタスクを実行します。過剰な JavaScript コードを実行すると、メインスレッドがブロックされ、ブラウザがこれらのタスクを実行するのを遅らせ、ユーザー エクスペリエンスの低下につながる可能性があります。
iOS / Android アプリの開発では、アプリのメインスレッドがユーザー イベントに自由に応答できるようにするための一般的なパターンとして、オペレーションを別のスレッドにオフロードします。実際、最新バージョンの Android では、メインスレッドを長時間ブロックするとアプリがクラッシュします。
ウェブでは、JavaScript はシングル スレッドのコンセプトに基づいて設計されており、アプリが持つようなマルチスレッド モデルを実装するために必要な機能(共有メモリなど)がありません。
こうした制限があるものの、ウェブでも同様のパターンを実現できます。ワーカーを使用してバックグラウンド スレッドでスクリプトを実行することで、メインスレッドに干渉することなくタスクを実行できます。ワーカーは、共有メモリを使用せずに、別のスレッドで実行される JavaScript スコープ全体です。
この投稿では、2 種類のワーカー(ウェブワーカーとサービス ワーカー)について、類似点と相違点、本番環境のウェブサイトで使用する際の一般的なパターンについて説明します。
ウェブワーカーとサービス ワーカー
類似点
ウェブサイトで使用できるワーカーには、ウェブワーカーとサービス ワーカーの 2 種類があります。これらには、次のような共通点があります。
- どちらもセカンダリ スレッドで実行されるため、メインスレッドとユーザー インターフェースをブロックすることなく JavaScript コードを実行できます。
WindowオブジェクトとDocumentオブジェクトにアクセスできないため、DOM を直接操作することはできません。また、ブラウザ API へのアクセスも制限されています。
相違点
ウェブワーカーに委任できるほとんどの処理は、サービス ワーカーでも実行できると考えられますが、両者には重要な違いがあります。
- ウェブワーカーとは異なり、サービス ワーカーを使用すると、ネットワーク リクエストを(
fetchイベントを介して)インターセプトし、バックグラウンドで(pushイベントを介して)Push API イベントをリッスンできます。 - 1 つのページで複数のウェブワーカーを生成できますが、1 つのサービス ワーカーが、登録されたスコープ内のすべてのアクティブなタブを制御します。
- ウェブワーカーのライフスパンは、それが属するタブと密接に関連していますが、Service Worker のライフサイクルはそれとは独立しています。そのため、ウェブワーカーが実行されているタブを閉じると、ウェブワーカーは終了します。一方、サービス ワーカーは、サイトにアクティブなタブが開いていない場合でも、バックグラウンドで実行を継続できます。
ユースケース
2 種類のワーカーの違いから、どちらを使用すべきかがわかります。
ウェブワーカーのユースケースは、UI のブロックを回避するために、作業(重い計算など)をセカンダリ スレッドにオフロードすることに関連しています。
- 例: ビデオゲーム PROXX を構築したチームは、ユーザー入力とアニメーションを処理するために、メインスレッドをできるだけ空けておきたいと考えました。これを実現するために、ウェブワーカーを使用して、ゲームロジックと状態の維持を別のスレッドで実行しました。
サービス ワーカーのタスクは、一般的に、ネットワーク プロキシとしての動作、バックグラウンド タスクの処理、キャッシュやオフラインなどの処理に関連しています。
例: ポッドキャスト PWA では、ユーザーがエピソード全体をダウンロードしてオフラインで聴けるようにしたい場合があります。この目的には、Service Worker、特に Background Fetch API を使用できます。これにより、エピソードのダウンロード中にユーザーがタブを閉じても、タスクは中断されません。
ツールとライブラリ
ウィンドウとワーカーの通信は、さまざまな下位レベルの API を使用して実装できます。幸い、このプロセスを抽象化して、最も一般的なユースケースに対応するライブラリがあります。このセクションでは、ウィンドウからウェブワーカーとサービス ワーカーをそれぞれ処理する 2 つのライブラリ(Comlink と Workbox)について説明します。
コムリンク
Comlink は、Web Worker を使用するウェブサイトを構築する際に、多くの基盤となる詳細を処理する、小さな(1.6k)RPC ライブラリです。PROXX や Squoosh などのウェブサイトで使用されています。その動機とコードサンプルの概要については、こちらをご覧ください。
Workbox
Workbox は、サービス ワーカーを使用するウェブサイトを構築するための一般的なライブラリです。キャッシュ保存、オフライン、バックグラウンド同期などに関する一連のベスト プラクティスがパッケージ化されています。workbox-window モジュールを使用すると、サービス ワーカーとページの間でメッセージを簡単に交換できます。
次のステップ
このシリーズの残りの部分では、ウィンドウと Service Worker の通信のパターンに焦点を当てます。
- 命令型キャッシュ ガイド: ページから Service Worker を呼び出して、リソースを事前にキャッシュに保存します(プリフェッチ シナリオなど)。
- 更新をブロードキャストする: 重要な更新(ウェブサイトの新しいバージョンが利用可能になったなど)を通知するために、Service Worker からページを呼び出します。
- 双方向通信: サービス ワーカーにタスク(重いダウンロードなど)を委任し、ページに進捗状況を通知します。
ウィンドウとウェブワーカーの通信パターンについては、ウェブワーカーを使用してブラウザのメインスレッドから JavaScript を実行するをご覧ください。