前回は、効率的な双方向通信が実現できる技術である WebSocketについてまとめた。ここでは、マルチスレッドによってユーザビリティを向上できる Web Workersについて解説する。
1 Web Workers概要
Web Workersとは
Web Workersは新しいJavaScript実行環境を別スレッドで生成し、JavaScriptコードをバックグラウンドで処理させるための仕組みである。ユーザのUI操作を妨げない、ユーザビリティの高いWebアプリケーションを開発できる。
Web Workersの動作
ここでは通常のクライアントサイドJavaScript実行環境をメインスレッド、Web Workersにより生成されるバックグラウンドのJavaScript実行環境をワーカと呼ぶ。ワーカはメインスレッドから生成される。またワーカは複数生成できる。
メインスレッドとワーカのJavaScript実行環境は分離されていて、お互いの環境の変数は参照できない。ワーカの環境からはdocumentオブジェクトを参照できない。
2 基本操作
ワーカの生成
ワーカを生成するにはメインスレッドからWorkerのコンストラクタを呼び出す。ワーカで実行させたいJavaScriptコードが書かれたファイルのURLをコンストラクタの引数に指定することで、ファイルに書かれたコードがバックグラウンド度実行される。
メインスレッド側のメッセージ送受信
メインスレッドからワーカにメッセージを送信するには、WorkerインスタンスのpostMessageメソッドを呼び出す。ワーカからのメッセージを受信するには、Workerインスタンスのmessageイベントを捕捉する。
ワーカ側のメッセージ送受信
ワーカからメインスレッドにメッセージを送信するには、ワーカのグローバルオブジェクトに定義されているpostMessageメソッドを呼び出す。メインスレッドからのメッセージを受信するには、グローバルオブジェクトのmessageイベントを捕捉する。
ワーカの削除
ワーカを削除するには、メインスレッド側から削除する方法とワーカ側から自身を削除する方法の2通りがある。メインスレッド側からワーカを削除するにはWorkerインスタンスのterminateメソッドを呼び出す。ワーカ側から自身を削除するにはcloseメソッドを呼び出す。
外部ファイルの読み込み
ワーカ内から外部のJavaScriptファイルを読み込むには、importScriptsメソッドを呼び出す。importScriptsのファイル読み込みは同期的に行われるため、ファイルの読み込み待ちを考慮する必要はない。
3 Web Workers実践
これから作るサンプルは、テキストボックスに文字を入力するとクライアント側でユーザ名を検索して表示するというものである。検索処理をWeb Workersを用いてバックグラウンドで実行することで、重い検索処理中でもブロックしないUIが実現できる。
ワーカの利用
ワーカでは受け取った文字列から正規表現を生成し、大量のユーザデータを順に正規表現で検索し、すべてのユーザデータのチェックを終えたらマッチした結果をメインスレッドに返している。次にメインスレッド側ではテキストボックスでキーが入力されるたびにワーカに検索処理をリクエストしている。
ワーカの処理を中断する
前述のサンプルには大きな問題がある。それは、ワーカで検索処理を実行中に次の検索依頼を受け取った場合に、前の検索処理が終了するまで次の検索処理を開始できないことである。この問題を解決するためには、ワーカの処理を任意のタイミングで中断できる必要がある。これには大きく以下の2つの方法がある。
- ワーカを再生成する(メインスレッド側での対応):ワーカ側のコードを改修する必要がないが、ワーカを再生成するコストが課題
- タイマーを利用する(ワーカ側での対応):ワーカの生成コストがかからないが、ワーカのコードが複雑かつ処理終了までの時間が長くなることが課題
4 共有ワーカ
共有ワーカとは
共有ワーカは1つのワーカを複数のページで共有して参照できるものである。Same Origin Policyの制約はあるが、複数の異なるウィンドウから1つの共有ワーカを参照できる。共有ワーカの応用例として、共有ワーカを経由したウィンドウ間メッセージングや、共有ワーカをハブとしたサーバコネクションの1本化などが考えられている。
共有ワーカの生成
共有ワーカを生成するにはSharedWorkerクラスのコンストラクタを呼び出す。第1引数には通常のワーカと同様にJavaScriptファイルのURLを指定し、第2引数には共有ワーカにつける名前を指定する。第2引数を省略した場合は空文字として扱われる。
共有ワーカのメッセージ送受信
共有ワーカでメッセージを送受信するには、内部ではチャネルメッセージングが利用される。チャネルメッセージングとは、MessagePortと呼ばれる2つ1組オブジェクトを介してメッセージングを行う仕組みである。片方のMessagePortオブジェクトからpostMessageを呼び出すと、もう片方のMessagePortオブジェクトでmessageイベントが発火する。
メインスレッドではportというプロパティを使って、通常のワーカと同様にメッセージの送受信ができる。メインスレッド側でSharedWorkerインスタンスが生成されると、共有ワーカではconnectイベントが発火する。
共有ワーカの削除
メインスレッド側から個別にコネクションを閉じたい場合は、MessagePortのcloseメソッドを呼ぶ。参照しているウィンドウが残っている間は共有ワーカが削除されることはなく、最後の参照が切られた時点で共有ワーカが削除される。
共有ワーカの応用例
- ウィンドウ間通信:共有ワーカでMessagePortを管理することで、共有ワーカを経由して異なるウィンドウ同士のメッセージングが実現できる
- サーバコネクションの集約:共有ワーカをハブとしてサーバコネクションを1本化できる
最後に
マルチスレッドによるユーザビリティが向上できる Web Workers についてまとめた。
Web Workersは新しいJavaScript実行環境を別スレッドで生成し、JavaScriptコードをバックグラウンドで処理させるための仕組みである。ユーザのUI操作を妨げない、ユーザビリティの高いWebアプリケーションを開発できる。共有ワーカという1つのワーカを複数のページで共有して参照できる仕組みもあり、非常に可能性の感じられる技術となっている。
次回は、アプリとシステムの間の境界 通信規約であるWeb API について解説する。
![]() |