労働者と共有労働者

すべての一般的な言語にはスレッドがあります。 ブラウザーベースのJavaScriptでは、ワーカーは並列処理に使用されます。
猫の下には、それらの使用方法、ワーカーの制限、さまざまなブラウザーでの対話の機能に関するストーリーがあります。


労働者とは


UIをブロックしないバックグラウンドタスクを実行するための個別のコンテキスト。 通常、ワーカーは個別のスクリプトとして作成され、ワー​​カーのリソースはページの作成プロセスに存在します。 共有ワーカーは同じですが、複数のページから使用できます。
労働者には次のものがあります。


ワーカーを作成する


ワーカーは別のスクリプトから作成されます。
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 / osxFirefox / osxサファリ/ OSXChrome / winFirefox /勝利IE11 /勝利
ウェブ20 80048,00063,00041,90051,00063,000
労働者5,30043,3006 10021 30037,00030 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のシリアル化とは異なります。 アルゴリズムは次のことができます。

しかし、できません:


譲渡可能物


参照によって何かを転送できます。 これを行うには、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 / osxFF / OSXサファリ/ OSXChrome / winFf /勝利IE11 /勝利
専用:10B9 3008,40021,0006,8007 3003,200
専用:10kB4,0007,0005,0003,0005,0001 800
専用:1MB805009060400200
専用:10MB840775230
専用:trlist:10MB8,4001,1002,5006,2001 9002,200
共有:10B3 1008 300-2,2005 500-
共有:10kB1 8006 900-1,4004,500-
共有:1MB40500-32400-
共有:10MB440-453-
共有:trlist:10MB-260--1 800-
shared-ipc:10B3,000--2,700--
shared-ipc:10kB1,600--1,700--
shared-ipc:1MB40--30--
shared-ipc:10MB4--3--

データから導き出せる結論:


労働者を殺す


worker.terminate()を呼び出すと、decicated workerを殺すことができます。 これは共有ワーカーでは不可能であり、その実行は停止されます:

共有ワーカーからプロセスキャッシュを呼び出してみましょう。 もちろん、労働者と一緒に、彼を作成したタブも落ちます。 まだ使用されているタブでは、次のメッセージが表示されます。


残念ながら、現在、ワーカーまたはそれを使用しているページの閉鎖を追跡する定期的な方法はありません。

Chromeの共有ワーカーのリソースアカウンティング


SharedWorkerは、プロセスを作成したページでプロセスを実行します。 考慮され、ワー​​カーが消費するCPUとメモリがタスクマネージャーに表示されます。 ページが閉じられている場合、ワーカーとのプロセスはページで使用されているメモリを放棄し(閉じてからしばらくしてからではなく)、他のページがこのワーカーを使用している間は存続します。 この場合、このようなプロセスがクロム統計から完全に消えることは興味深いことです。メモリもCPUも内部タスクマネージャで追跡できません。 これは不快です ユーザーはおそらく、ブラウザが多くのリソースを消費し始めた理由を推測しないでしょう。

デバッグワーカー


Chromeでは、共有ワーカーはchrome:// inspect /#workersページで利用可能です:

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

デバッグ機能を備えた他のブラウザーでは、ワーカーは依然として悪いです。

使用できますか...


Can I Useのさまざまなワーカーのサポート。 簡単に言えば、今日のWebに関しては、ワーカーは最新のブラウザーを使用し、sharedworkerは高度なデスクトップブラウザーを使用し、serviceworkerは早すぎます。

...


書かれたものはすべて2015年夏に関連しています。ウェブが急速に変化していることを忘れないでください。

参照資料


Web Workers(MDN)を使用する
Web Workersの基本
生活水準:ウェブワーカー
譲渡可能なオブジェクト
Web Workerはどれくらいの速度ですか?

Source: https://habr.com/ru/post/J261307/


All Articles