猫の下には、それらの使用方法、ワーカーの制限、さまざまなブラウザーでの対話の機能に関するストーリーがあります。
労働者とは
UIをブロックしないバックグラウンドタスクを実行するための個別のコンテキスト。 通常、ワーカーは個別のスクリプトとして作成され、ワーカーのリソースはページの作成プロセスに存在します。 共有ワーカーは同じですが、複数のページから使用できます。
労働者には次のものがあります。
- ナビゲーター
- 場所
- applicationCache
- XHR、websocket
- 同期スクリプト読み込み用のimportScripts
ワーカーを作成する
ワーカーは別のスクリプトから作成されます。
var worker = new Worker(scriptUrl); var sharedWorker = new SharedWorker(scriptUrl);
共有ワーカーはURLで識別されます。 1つのファイルから2番目のワーカーを作成するには、URLにパラメーターを追加します(worker.js?Num = 2)。
ワーカーは、別個のファイルなしで作成できます。 たとえば、関数テキストから作成します。
var code = workerFn.toString(); code = code.substring(code.indexOf("{")+1, code.lastIndexOf("}")); var blob = new Blob([code], {type: 'application/javascript'}); worker = new Worker(URL.createObjectURL(blob));
ワーカーからワーカーを作成できるのは、Firefoxのみです。 Chromeでは、ページから共有ワーカーを作成し、そのポートを別のワーカーに転送できます(詳細は以下を参照)。
労働者の制限
ドム
ワーカーでは、DOMを使用できません;ウィンドウの代わりに、グローバルオブジェクトはselfと呼ばれます。 localStorageにアクセスしてキャンバスに描画できません。 通常、すべてのデスクトップAPIに同じ制限があります:UIスレッドからのみウィンドウにアクセスします。
施設へのアクセス
オブジェクトをワーカーから返すことはできません。 javascriptにはロックやその他のスレッドセーフ機能はないため、ワーカーからの参照によるオブジェクトの転送はできません。ワーカーとの間で送受信されるものはすべてコピーされます。
CORS
これまでのところ、ワーカーはCORSをサポートしておらず、ドメインからダウンロードすることによってのみワーカーを作成できます。
スタックサイズ
ワーカーの場合、より小さいスタックサイズが割り当てられます。重要な場合があります。
Chrome / osx | Firefox / osx | サファリ/ OSX | Chrome / win | Firefox /勝利 | IE11 /勝利 | |
---|---|---|---|---|---|---|
ウェブ | 20 800 | 48,000 | 63,000 | 41,900 | 51,000 | 63,000 |
労働者 | 5,300 | 43,300 | 6 100 | 21 300 | 37,000 | 30 100 |
コンソール
最近までそうではありませんでしたが、通常はすでにそうです。 一部のブラウザーでは、ワーカーにコンソールがないため、アクセスする前にその可用性を確認することをお勧めします。
労働者の相互作用
ワーカーを作成したら、彼にメッセージを送信できます。
worker.postMessage({hello: 'world'}); worker.onmessage = function(e) { e.data ... }; sharedWorker.port.postMessage({hello: 'world'}); sharedWorker.port.onmessage = function(e) { e.data... };
ワーカーで次のようなメッセージをサブスクライブします。
// worker self.onmessage = function(e) { e.data... }; // shared worker self.onconnect = function(e) { var port = e.ports[0]; port.onmessage = function(e) { e.data... }; };
同様に、またその逆に、ワーカーからself.postMessageまたはport.postMessageを共有ワーカーに対して呼び出すことができます。
postMessageメソッドは、 構造化クローンアルゴリズムを使用してオブジェクトをクローンします。 これはJSONのシリアル化とは異なります。 アルゴリズムは次のことができます。
- RegExp、Blob、File、ImageDataのコピー
- 循環参照を復元する
しかし、できません:
- エラー、関数、DOM要素(エラーが発生します)
- プロパティとプロトタイプ(傾斜していません)
譲渡可能物
参照によって何かを転送できます。 これを行うには、postMessageに2番目のパラメーターtransferListがあります。
var ab = new ArrayBuffer(size); worker.postMessage({ data: ab }, [ab]);
transferListでは、移動するオブジェクトのリストを渡すことができます。 ArrayBufferとMessagePortのみがサポートされています。 呼び出しコンテキストでは、オブジェクトは削除されます。ArrayBufferの長さはゼロであり、再送信を試みるとエラーになります。
Uncaught DOMException: Failed to execute 'postMessage' on 'Worker': An ArrayBuffer is neutered and could not be cloned.
2人の労働者の相互作用
Firefoxでは、ワーカーからワーカーを作成できます(標準ではサブワーカーが定義されています )。
クロムでは、ワーカーからワーカーを作成することはできません。また、ワーカーは相互にやり取りする必要がある場合があります。 最も簡単な方法は、ページコードを使用してメッセージを送信することです。 ただし、これは次の理由で不便です。1。追加のコードを記述する必要がある、2。インタラクションとデータのコピーの回数が2倍になる、3。UIコンテキストでコードを実行する必要がある
ワーカーに共有ワーカーと通信し、共有ワーカーポートを渡すように指示すると、UIコンテキストで送信されたポートが失われます。 必要な場合は、共有ワーカーに再接続して再度作成する必要があります。 ポート転送は次のようになります。
worker.postMessage({ port: sharedWorker.port }, [sharedWorker.port]); // worker- -
確かに、同期のために、V8エンジンは引き続きUIコンテキストを使用します。これは、ページをしばらくハングさせることで見ることができます。
PostMessageのパフォーマンス
パフォーマンスは、いくつかのケース、異なるデータサイズ、およびtransferList(trlist)の使用によって異なります。
- 専任の労働者
- 作成されたプロセスの共有ワーカー
- 別のプロセスの共有ワーカー
この表は、1秒あたりのワーカーからのデータ転送サイクルとその逆のサイクルを示しています。
Chrome / osx | FF / OSX | サファリ/ OSX | Chrome / win | Ff /勝利 | IE11 /勝利 | |
---|---|---|---|---|---|---|
専用:10B | 9 300 | 8,400 | 21,000 | 6,800 | 7 300 | 3,200 |
専用:10kB | 4,000 | 7,000 | 5,000 | 3,000 | 5,000 | 1 800 |
専用:1MB | 80 | 500 | 90 | 60 | 400 | 200 |
専用:10MB | 8 | 40 | 7 | 7 | 52 | 30 |
専用:trlist:10MB | 8,400 | 1,100 | 2,500 | 6,200 | 1 900 | 2,200 |
共有:10B | 3 100 | 8 300 | - | 2,200 | 5 500 | - |
共有:10kB | 1 800 | 6 900 | - | 1,400 | 4,500 | - |
共有:1MB | 40 | 500 | - | 32 | 400 | - |
共有:10MB | 4 | 40 | - | 4 | 53 | - |
共有:trlist:10MB | - | 260 | - | - | 1 800 | - |
shared-ipc:10B | 3,000 | - | - | 2,700 | - | - |
shared-ipc:10kB | 1,600 | - | - | 1,700 | - | - |
shared-ipc:1MB | 40 | - | - | 30 | - | - |
shared-ipc:10MB | 4 | - | - | 3 | - | - |
データから導き出せる結論:
- Chromeの専用ワーカーとのやり取りのコストは、共有の場合よりも少なくなります。
- transferListを使用した大量のデータの転送ははるかに高速です。
- ただし、transferListはリンクまたは数バイトの送信と同等ではありません。
労働者を殺す
worker.terminate()を呼び出すと、decicated workerを殺すことができます。 これは共有ワーカーでは不可能であり、その実行は停止されます:
- self.close()を呼び出して自身を閉じるとき
- それを使用するすべてのページが閉じられたとき(ワーカーが計算を終了する機会がない間)
- ユーザーが強制的に終了したとき(たとえば、chrome from chrome:// inspect)
- 彼が落ちるとき、または彼が住んでいるページのプロセス
共有ワーカーからプロセスキャッシュを呼び出してみましょう。 もちろん、労働者と一緒に、彼を作成したタブも落ちます。 まだ使用されているタブでは、次のメッセージが表示されます。

残念ながら、現在、ワーカーまたはそれを使用しているページの閉鎖を追跡する定期的な方法はありません。
Chromeの共有ワーカーのリソースアカウンティング
SharedWorkerは、プロセスを作成したページでプロセスを実行します。 考慮され、ワーカーが消費するCPUとメモリがタスクマネージャーに表示されます。 ページが閉じられている場合、ワーカーとのプロセスはページで使用されているメモリを放棄し(閉じてからしばらくしてからではなく)、他のページがこのワーカーを使用している間は存続します。 この場合、このようなプロセスがクロム統計から完全に消えることは興味深いことです。メモリもCPUも内部タスクマネージャで追跡できません。 これは不快です ユーザーはおそらく、ブラウザが多くのリソースを消費し始めた理由を推測しないでしょう。
デバッグワーカー
Chromeでは、共有ワーカーはchrome:// inspect /#workersページで利用可能です:

これは、ワーカーからのコンソール出力が書き込まれる場所です。
ChromeとIEの専用ワーカーは、それが実行されているページでデバッグされます。

デバッグ機能を備えた他のブラウザーでは、ワーカーは依然として悪いです。
使用できますか...
Can I Useのさまざまなワーカーのサポート。 簡単に言えば、今日のWebに関しては、ワーカーは最新のブラウザーを使用し、sharedworkerは高度なデスクトップブラウザーを使用し、serviceworkerは早すぎます。
...
書かれたものはすべて2015年夏に関連しています。ウェブが急速に変化していることを忘れないでください。
参照資料
Web Workers(MDN)を使用する
Web Workersの基本
生活水準:ウェブワーカー
譲渡可能なオブジェクト
Web Workerはどれくらいの速度ですか?