読者です 読者をやめる 読者になる 読者になる

tanaka's Programming Memo

プログラミングについてのメモ。

パーフェクトJavaScript勉強メモ(18)

前へ | 次へ

18章 WebWorkers

WebWorkers概要

p408 WebWorkersとは
WebWorkersの動作
  • 通常のJavaScript実行環境をメインスレッド、Web Workersにより生成されるバックグラウンドのものをワーカと書籍では呼ぶ
  • ワーカは複数生成できる
  • メインスレッドとワーカの変数はお互いにアクセスできない
  • メインスレッドのグローバルオブジェクトはwindow、ワーカのグローバルオブジェクトはselfという名前で参照
  • p409 ワーカはdocumentにアクセスできないのでUIはいじれない
  • データのやりとりはpostMessageメソッドとmessageイベントで行う

基本操作

ワーカの生成
  • ワーカを生成するには、ワーカ用のJavaScriptファイルを指定して、Workerオブジェクトをnewする
  • ワーカのJavaScriptは同一オリジンポリシーが適用される
メインスレッド側のメッセージ送受信
  • p410 postMessageメソッドで送信する。データの型は自由。ただし、documentオブジェクトなどの特殊なものは除く
  • ワーカからのメッセージを受信するには、Workerインスタンスのmessageイベントを捕捉する
  • 受信データは、messageイベントオブジェクトのdataプロパティに格納される
ワーカ側のメッセージ送受信
  • ワーカのグローバルオブジェクトのpostMessageメソッドを呼び出す。送信できるのはメインスレッドと同様
  • メインスレッドからのデータの受信は、グローバルオブジェクトのmessageイベントを捕捉する
  • 受信データは、messageイベントオブジェクトのdataプロパティに格納
  • p411 グローバルオブジェクトはselfを省略できるが、間違いをなくすために明示するのも手
ワーカの削除
  • Google Chromeでは、TaskManagerでワーカの消費容量が確認できる
  • メインスレッドから削除するには、ワーカのterminateメソッドを呼び出す
  • ワーカが自分で削除するには、closeメソッドを呼び出す
  • ワーカ処理が頻繁に利用される場合など、そのまま使いまわしてもよい
外部ファイルの読み込み
  • ワーカ内から外部のファイルを読み込むには、importScriptsメソッドを利用する。同一オリジンポリシーは適用されない
  • importScriptsは同期的に実行される
  • p412 コンマ区切りで複数のファイルを指定できる

WebWorkersの実践

ワーカの利用
  • p413 重そうな処理をワーカ側で実装してメインスレッドの負荷を減らす方法と、ワーカはデータを用意するだけで残りはメイン側で実装してロジックを切り分けてシンプルな構造にする方法がある
  • いずれかは時と場合に応じて判断する
ワーカの処理を中断する
  • p414 ワーカ実行中に、次の要求が発生した場合など、現在動作中のワーカを中断する必要がある
  • ワーカを再生成する
    • メインスレッドでメッセージを送信する際に、古いワーカを破棄して自動的にワーカを中断して、新しいワーカを生成する
    • メリットは、ワーカ側の実装がそのままでよいこと
    • デメリットはワーカを再生成するコスト
    • 再生成が頻繁に発生すると、コストがバカにならない
  • タイマーを利用する
    • p415 大きな処理をタイマーで細切れにすることで、messageイベントが割り込めるようにして、自分でキャンセルできるようにする
    • デメリットは、ワーカコードの複雑化と、処理完了までのトータル時間が長くなること
    • 書籍の例では、100行ずつ区切って検索することで、割り込みが発生できるようにしている

共有ワーカ

共有ワーカとは
  • p416 1つのワーカを複数のページで共有できる
  • 同一オリジンポリシーは適用される
  • メリットは、リソースの削減、ワーカの生成コストの削減、共有ワーカを利用したウィンドウ間通信
共有ワーカの生成
  • SharedWorkerクラスのコンストラクタを呼び出す
  • 第1引数はワーカのJavaScript。第2引数には共有ワーカにつける名前。省略すると空文字
  • 異なるウィンドウから同じJavaScriptファイルと共有ワーカ名を指定してSharedWorkerコンストラクタを実行すると、すでに生成された共有ワーカがあれば同じ共有ワーカを参照したSharedWorkerインスタンスが返る
共有ワーカのメッセージ送受信
  • 補足:2015/2/12現在、IESafariスマホブラウザで未対応
  • p417 送信先を特定する必要がある
  • MessagePortと呼ばれる2つ1組のオブジェクトを介してメッセージングを行う
  • 片方のMessagePortオブジェクトからpostMessageを呼び出すと、もう片方のMessagePortオブジェクトでmessageイベントが発火する
  • メインスレッドで生成したSharedWorkerインスタンスは、portプロパティにMessagePortオブジェクトの片方を持つ
  • メインスレッドはこれを使ってメッセージングする
  • p418 メインスレッド側でSharedWorkerインスタンスを生成すると、共有ワーカ側ではconnectイベントが発火する
  • connectイベントはメインスレッドと通信できるMessagePortを持つ
共有ワーカの削除
  • SharedWorkerインスタンスはterminateメソッドを持たない
  • メインスレッドから通信を終える場合はcloseメソッドを呼ぶ
  • すべての接続が切断されたら、共有ワーカは消える
  • 共有ワーカ側でcloseすると任意のタイミングで自分自身を削除できる
共有ワーカの応用例
  • p419 ウィンドウ間通信の例
  • WebSocketを使ってサーバと通信するアプリにおいて、個別のウィンドウすべてがWebSocketを接続するとconnect数が増えてしまうので、共有ワーカにWebSocketを一本化するなど
  • ワーカは破棄せず、使い回せるか。中断するとワーカの再生成が必要だったかも

前へ | 次へ