18章 WebWorkers
WebWorkers概要
p408 WebWorkersとは
WebWorkersの動作
- 通常のJavaScript実行環境をメインスレッド、Web Workersにより生成されるバックグラウンドのものをワーカと書籍では呼ぶ
- ワーカは複数生成できる
- メインスレッドとワーカの変数はお互いにアクセスできない
- メインスレッドのグローバルオブジェクトはwindow、ワーカのグローバルオブジェクトはselfという名前で参照
- p409 ワーカはdocumentにアクセスできないのでUIはいじれない
- データのやりとりはpostMessageメソッドとmessageイベントで行う
基本操作
ワーカの生成
- ワーカを生成するには、ワーカ用のJavaScriptファイルを指定して、Workerオブジェクトをnewする
- ワーカのJavaScriptは同一オリジンポリシーが適用される
メインスレッド側のメッセージ送受信
ワーカ側のメッセージ送受信
- ワーカのグローバルオブジェクトのpostMessageメソッドを呼び出す。送信できるのはメインスレッドと同様
- メインスレッドからのデータの受信は、グローバルオブジェクトのmessageイベントを捕捉する
- 受信データは、messageイベントオブジェクトのdataプロパティに格納
- p411 グローバルオブジェクトはselfを省略できるが、間違いをなくすために明示するのも手
ワーカの削除
- Google Chromeでは、TaskManagerでワーカの消費容量が確認できる
- メインスレッドから削除するには、ワーカのterminateメソッドを呼び出す
- ワーカが自分で削除するには、closeメソッドを呼び出す
- ワーカ処理が頻繁に利用される場合など、そのまま使いまわしてもよい
WebWorkersの実践
ワーカの利用
- p413 重そうな処理をワーカ側で実装してメインスレッドの負荷を減らす方法と、ワーカはデータを用意するだけで残りはメイン側で実装してロジックを切り分けてシンプルな構造にする方法がある
- いずれかは時と場合に応じて判断する
ワーカの処理を中断する
- p414 ワーカ実行中に、次の要求が発生した場合など、現在動作中のワーカを中断する必要がある
- ワーカを再生成する
- メインスレッドでメッセージを送信する際に、古いワーカを破棄して自動的にワーカを中断して、新しいワーカを生成する
- メリットは、ワーカ側の実装がそのままでよいこと
- デメリットはワーカを再生成するコスト
- 再生成が頻繁に発生すると、コストがバカにならない
- タイマーを利用する
- p415 大きな処理をタイマーで細切れにすることで、messageイベントが割り込めるようにして、自分でキャンセルできるようにする
- デメリットは、ワーカコードの複雑化と、処理完了までのトータル時間が長くなること
- 書籍の例では、100行ずつ区切って検索することで、割り込みが発生できるようにしている
共有ワーカ
共有ワーカとは
- p416 1つのワーカを複数のページで共有できる
- 同一オリジンポリシーは適用される
- メリットは、リソースの削減、ワーカの生成コストの削減、共有ワーカを利用したウィンドウ間通信
共有ワーカの生成
- SharedWorkerクラスのコンストラクタを呼び出す
- 第1引数はワーカのJavaScript。第2引数には共有ワーカにつける名前。省略すると空文字
- 異なるウィンドウから同じJavaScriptファイルと共有ワーカ名を指定してSharedWorkerコンストラクタを実行すると、すでに生成された共有ワーカがあれば同じ共有ワーカを参照したSharedWorkerインスタンスが返る
共有ワーカのメッセージ送受信
- 補足:2015/2/12現在、IE、Safari、スマホブラウザで未対応
- p417 送信先を特定する必要がある
- MessagePortと呼ばれる2つ1組のオブジェクトを介してメッセージングを行う
- 片方のMessagePortオブジェクトからpostMessageを呼び出すと、もう片方のMessagePortオブジェクトでmessageイベントが発火する
- メインスレッドで生成したSharedWorkerインスタンスは、portプロパティにMessagePortオブジェクトの片方を持つ
- メインスレッドはこれを使ってメッセージングする
- p418 メインスレッド側でSharedWorkerインスタンスを生成すると、共有ワーカ側ではconnectイベントが発火する
- connectイベントはメインスレッドと通信できるMessagePortを持つ