ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript Web Workers の構成要素と 5 つの使用シナリオ

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

coldplay.xixi
coldplay.xixi転載
2020-12-04 15:03:281939ブラウズ

これは、JavaScript とそれが構築するコンポーネントの探究に特化した JavaScript 列の一連の記事です。

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

関連する無料学習の推奨事項: javascript (ビデオ)

今回は、次のステップを実行します。 Web ワーカー を説明するには、簡単な概念から始めて、さまざまな種類の Web ワーカー とそのコンポーネントがどのように機能するかについて説明します。の連携と、さまざまなシナリオにおけるそれぞれの利点と制限について説明します。最後に、Web Workers を正しく使用するための 5 つのシナリオを示します。

前の記事で説明したように、JavaScript 言語はシングルスレッド モデルを使用していることを知っておく必要があります。ただし、JavaScript は開発者に非同期コードを作成する機会も提供します。

非同期プログラミングの制限

これまでの記事では、非同期プログラミングとそれを使用する必要がある場合について説明しました。

非同期プログラミングにより、UI インターフェイスの応答性が向上します (レンダリング速度が速くなります)。「コード スケジューリング」を通じて、時間を要求する必要があるコードが最初にイベント ループに配置され、後で実行されるため、UI は最初に表示をレンダリングします。

非同期プログラミングの良い使用例は、AJAX リクエストです。リクエストには時間がかかる場合があるため、非同期リクエストを使用すると、クライアントが応答を待っている間に他のコードを実行できます。

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

しかし、これによって問題が発生します - リクエストはブラウザの WEB API によって処理されますが、他のコードを非同期にするにはどうすればよいでしょうか? たとえば、成功した場合のコードは次のとおりです。コールバックは非常に CPU を集中的に使用します:

var result = performCPUIntensiveCalculation();

performCPUIntensiveCalculation が HTTP リクエストではなくブロッキング コード (大量のコンテンツを含む for ループなど) の場合、クリアする方法はありません。イベント ループが時間内に発生すると、ブラウザの UI レンダリングがブロックされ、ページは時間内にユーザーに応答できなくなります。

これは、非同期関数はシングルスレッド JavaScript 言語の制限のごく一部しか解決できないことを意味します。

場合によっては、setTimeout を使用して、長時間実行される計算をブロックできます。setTimeout を使用して、ページを取得するために計算を一時的に非同期キューに入れることができます。レンダリングが高速化。たとえば、複雑な計算を別々の setTimeout 呼び出しでバッチ処理することで、イベント ループ内の別々の「スポット」に配置でき、UI レンダリング/応答の実行時間を短縮できます。

数値の配列の平均を計算する単純な関数を見てください:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

上記のコードを書き換えて非同期性を「シミュレート」する方法は次のとおりです:

function averageAsync(numbers, callback) {
    var len = numbers.length,
        sum = 0;

    if (len === 0) {
        return 0;
    } 

    function calculateSumAsync(i) {
        if (i <p>setTimeout 関数を使用すると、計算の各ステップがイベント ループにさらに追加されます。各計算の間には、他の計算が行われるのに十分な時間があり、ブラウザーがレンダリングできるようになります。 </p><h2>Web Worker はこの問題を解決できます</h2><p>HTML5 は、次のような多くの新機能をもたらします:</p>
  • SSE (以前の記事ですでに言及しました。 WebSocket との比較)
  • 地理位置情報
  • アプリケーション キャッシュ
  • ローカル ストレージ
  • ドラッグ アンド ドロップ
  • Web ワーカー

Web Worker の概要

Web Worker の役割は、JavaScript 用のマルチスレッド環境を作成することです。これにより、メインスレッドがワーカー スレッドを作成し、後者にいくつかのタスクを割り当てることができるようになります。実行のためです。メイン スレッドの実行中、ワーカー スレッドはバックグラウンドで実行され、この 2 つは相互に干渉しません。ワーカー スレッドが計算タスクを完了するまで待ってから、結果をメイン スレッドに返します。この利点は、一部のコンピューティング集約型または高レイテンシーのタスクがワーカー スレッドの負担となり、メイン スレッド (通常は UI インタラクションを担当) がスムーズになり、ブロックされたり速度が低下したりしないことです。

「JavaScript はシングルスレッド言語ではないのですか?」と疑問に思うかもしれません。

実際、JavaScript はスレッド モデルを定義しない言語です。 Web ワーカーは JavaScript の一部ではありませんが、JavaScript を通じてアクセスできるブラウザ機能です。歴史的に、ほとんどのブラウザはシングルスレッドであり (もちろん、これは変わりました)、ほとんどの JavaScript 実装はブラウザ内で行われていました。 Web ワーカーは Node.JS には実装されていません。 Node.js には、cluster と child_process という同様の概念があり、これらもマルチスレッドですが、Web Workers とは異なります。

仕様には 3 種類の Web ワーカーが記載されていることに注意してください。

  • 専用ワーカー (専用ワーカー)
  • 共有ワーカー (共有ワーカー)
  • Service Worker (サービス ワーカー)

D dedicated Workers

D dedicated Worker には、それを作成したページからのみアクセスでき、そのページとのみ通信できます。ブラウザがサポートしているものは次のとおりです:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

Shared Workers

共享 Workers 在同一源(origin)下面的各种进程都可以访问它,包括:iframes、浏览器中的不同tab页(一个tab页就是一个单独的进程,所以Shared Workers可以用来实现 tab 页之间的交流)、以及其他的共享 Workers。以下是浏览器支持的情况:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

Service workers

Service Worker 功能:

  • 后台消息传递
  • 网络代理,转发请求,伪造响应
  • 离线缓存
  • 消息推送

在目前阶段,Service Worker 的主要能力集中在网络代理和离线缓存上。具体的实现上,可以理解为 Service Worker 是一个能在网页关闭时仍然运行的 Web Worker。以下是浏览器支持的情况:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

本文主要讨论 专用 Workers,没有特别声明的话,Web Workers、Workers都是指代的专用 Workers。

Web Workers 是如何工作

Web Workers 一般通过脚本为 .js 文件来构建,在页面中还通过了一些异步的 HTTP 请求,这些请求是完全被隐藏了的,你只需要调用 Web Worker API.

Worker 利用类线程间消息传递来实现并行性。它们保证界面的实时性、高性能和响应性呈现给用户。

Web Workers 在浏览器中的一个独立线程中运行。因此,它们执行的代码需要包含在一个单独的文件中。这一点很重要,请记住!

让我们看看基本 Workers 是如何创建的:

var worker = new Worker('task.js');

Worker() 构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。

为了启动创建的 Worker,需要调用 postMessage 方法:

worker.postMessage();

Web Worker 通信

为了在 Web Worker 和创建它的页面之间进行通信,需要使用 postMessage 方法或 Broadcast Channel。

postMessage 方法

新浏览器支持JSON对象作为方法的第一个参数,而旧浏览器只支持字符串。

来看一个示例,通过将 JSON 对象作为一个更“复杂”的示例传递,创建 Worker 的页面如何与之通信。传递字符串跟传递对象的方式也是一样的。

让我们来看看下面的 HTML 页面(或者更准确地说是它的一部分):

<button>Start computation</button>

<script>
  function startComputation() {
    worker.postMessage({&#39;cmd&#39;: &#39;average&#39;, &#39;data&#39;: [1, 2, 3, 4]});
  }
  var worker = new Worker(&#39;doWork.js&#39;);
  worker.addEventListener(&#39;message&#39;, function(e) {
    console.log(e.data);
  }, false);
  
</script>

然后这是 worker 中的 js 代码:

self.addEventListener('message', function(e) {
  var data = e.data;
  switch (data.cmd) {
    case 'average':
      var result = calculateAverage(data); // 从数值数组中计算平均值的函数
      self.postMessage(result);
      break;
    default:
      self.postMessage('Unknown command');
  }
}, false);

当单击该按钮时,将从主页调用 postMessage。postMessage 行将 JSON 对象传给Worker。Worker 通过定义的消息处理程序监听并处理该消息。

当消息到达时,实际的计算在worker中执行,而不会阻塞事件循环。Worker 检查传递的事件参数 e,像执行 JavaScript 函数一样,处理完成后,把结果传回给主页。

在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。

有两种方法可以停止 Worker:从主页调用 worker.terminate() 或在 worker 内部调用 self.close()

Broadcast Channel

Broadcast Channel API 允许同一原始域和用户代理下的所有窗口,iFrames 等进行交互。也就是说,如果用户打开了同一个网站的的两个标签窗口,如果网站内容发生了变化,那么两个窗口会同时得到更新通知。

还是不明白?就拿 Facebook 作为例子吧,假如你现在已经打开 了Facebook 的一个窗口,但是你此时还没有登录,此时你又打开另外一个窗口进行登录,那么你就可以通知其他窗口/标签页去告诉它们一个用户已经登录了并请求它们进行相应的页面更新。

// Connection to a broadcast channel
var bc = new BroadcastChannel('test_channel');

// Example of sending of a simple message
bc.postMessage('This is a test message.');

// Example of a simple event handler that only
// logs the message to the console
bc.onmessage = function (e) { 
  console.log(e.data); 
}

// Disconnect the channel
bc.close()

可以从下面这张图,在视觉上来清晰地感受 Broadcast Channel:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

Broadcast Channel 浏览器支持比较有限:

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

消息的大小

有两种方式发送消息给Web Workers:

  • コピー メッセージ : メッセージはシリアル化され、コピーされて送信され、もう一方の側で逆シリアル化されます。ページとワーカーは同じインスタンスを共有しないため、最終的にパスごとにコピーが作成されます。ほとんどのブラウザーは JSON を使用して両側で値をエンコードおよびデコードするため、データのデコードおよびエンコード操作は次のようになります。メッセージ送信プロセスの時間オーバーヘッドが増加します。メッセージが大きいほど、送信に時​​間がかかります。
  • 配信メッセージ : これは、元の送信者が送信後はそのメッセージを再度使用できないことを意味します。データの送信はほぼ瞬時に行われますが、この送信方法の制限は、ArrayBuffer タイプを使用してのみ転送できることです。

Web Workers で利用できる機能

JavaScript のマルチスレッドの性質により、Web Workers は JavaScript 機能のサブセットにしかアクセスできません。その機能の一部を次に示します。

Web ワーカーは、マルチスレッドの性質のため、JavaScript 機能のサブセットにのみアクセスできます。使用可能なプロパティのリストは次のとおりです。

  • navigator オブジェクト
  • location オブジェクト (読み取り専用)
  • MLHttpRequest
  • setTimeout()/ clearTimeout() および setInterval()/clearInterval()
  • アプリケーション キャッシュ
  • 使用importScripts()外部スクリプトのインポート
  • 他の Web ワーカーの作成

Web Workers の制限

残念ながら、Web Workers はいくつかの非常に重要な JavaScript 機能にアクセスできません:

  • DOM (スレッドが安全でない原因となります)
  • ウィンドウ オブジェクト
  • ドキュメント オブジェクト
  • 親オブジェクト

これは、Web Worker が DOM (したがって UI ) を操作できないことを意味します。これは難しい場合もありますが、Web ワーカーの正しい使用方法を理解すると、Web ワーカーを別個の「コンピューター」として使用し始め、すべての UI 変更がページ コード内で行われるようになります。作業者は面倒な作業をすべて実行し、完了すると結果をページに返します。

エラーの処理

JavaScript コードと同様に、Web ワーカーによってスローされたエラーも処理する必要があります。 Worker の実行中にエラーが発生した場合、ErrorEvent イベントがトリガーされます。このインターフェイスには、問題のトラブルシューティングに役立つ 3 つの便利なプロパティが含まれています。

  • filename - ワーカーのスクリプト名
  • lineno - エラーが発生します。行番号
  • メッセージ - エラーの説明

例は次のとおりです。

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

Inここでは、ワーカーを作成し、エラー イベントのリッスンを開始したことがわかります。

JavaScript Web Workers の構成要素と 5 つの使用シナリオ

ワーカー内 (workerWithError.js) では、 unknown#xxx に 2 を乗算して例外を作成します。例外は最初のスクリプトに伝播され、その後ページを通じてエラー イベントが監視され、エラーが捕捉されます。

5 優れた Web Workers アプリケーションの例

これまで、Web Workers の利点と制限を列挙してきました。次に、最も強力な使用例を見てみましょう:

  • レイトレーシング(ray tracing): レイトレーシングとは、光の軌跡をたどってピクセル単位で画像を生成するレンダリング技術です。レイ トレーシングでは、CPU を大量に使用する数学的計算を使用して光の経路をシミュレートします。この目的は、反射、屈折、マテリアルなどのいくつかの効果をシミュレートすることです。このすべての計算ロジックを Web ワーカーに追加して、UI スレッドのブロックを回避できます。さらに良いことに、画像レンダリングを複数のワーカー (および複数の CPU) 間で簡単に分割できます。これは、Web Workers を使用したレイ トレーシングの簡単なデモです - https://nerget.com/rayjs-mt/r... 。
  • 暗号化: 個人データや機密データに対する規制がますます厳しくなっているため、エンドツーエンドの暗号化がますます普及しています。頻繁に暗号化する必要があるデータが大量にある場合 (たとえば、サーバーに送信する前など)、暗号化は非常に時間がかかります。これは Web ワーカーを使用するのに最適なシナリオです。Web ワーカーは DOM や特別なものへのアクセスを必要とせず、純粋なアルゴリズムがその役割を果たします。 Web Worker で作業している限り、エンド ユーザーにとってはシームレスであり、エクスペリエンスには影響しません。
  • データのプリフェッチ: Web サイトまたは Web アプリケーションを最適化し、データの読み込み時間を短縮するために、Web ワーカーを使用して一部のデータを事前に読み込み、保存し、いつでも読み込めるようにすることができます。必要です。後で使用します。ワーカーを使用しない場合とは異なり、Web ワーカーはアプリケーションの UI に影響を与えないため、この場合に最適です。
  • プログレッシブ Web アプリケーション (プログレッシブ Web アプリケーション): この種類のプログレッシブ Web アプリケーションでは、ユーザー ネットワークが不安定な状況でも迅速にロードできる必要があります。これは、データをブラウザーにローカルに保存する必要があることを意味します。ここでも、IndexDB または同様の API が活躍します。通常、クライアント側のストレージが必要ですが、UI レンダリング スレッドをブロックせずにストレージを使用する場合は、作業をワーカーで行う必要があります。ただし、IndexDB を例に挙げると、いくつかの非同期 API が提供されており、それらを呼び出すために Web ワーカーを使用する必要はありませんが、同期 API の場合はワーカーで使用する必要があります。
  • スペル チェック: 基本的なスペル チェック プログラムのワークフローは次のとおりです。プログラムは、正しく綴られた単語のリストが含まれる辞書ファイルを読み取ります。実際のテキスト検索をより効率的に行うために、辞書は検索ツリーに解析されます。単語がチェッカーに提供されると、プログラムはその単語が事前に構築された検索ツリーに存在するかどうかをチェックします。単語がツリー内に見つからない場合は、置換文字を置き換えて、それがユーザーが書きたい単語であるかどうかをテストし、それが有効な単語であるかどうかをテストすることで、ユーザーに代替スペルを提供できます。これらの処理はすべて Web Worker 上で行うことができ、ユーザーはブロックされることなく単語や文章を入力することができ、Web Worker がバックグラウンドで単語が正しいかどうかをチェックし、代替単語を提供します。

# プログラミングについてさらに詳しく知りたい場合は、php トレーニング# に注目してください。 ## カラム!

以上がJavaScript Web Workers の構成要素と 5 つの使用シナリオの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。