>  기사  >  웹 프론트엔드  >  JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

coldplay.xixi
coldplay.xixi앞으로
2020-12-04 15:03:281939검색

이 글은 JavaScript 칼럼에 있는 일련의 기사로, javascript와 자바스크립트가 구축하는 구성 요소를 살펴봅니다. ㅋㅋㅋ 작업자

, 해당 구성 요소가 함께 작동하는 방식, 다양한 시나리오에서 각각의 장점과 한계. 마지막으로

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오Web Workers

의 올바른 사용을 위한 5가지 시나리오를 제공합니다.

이전 기사에서 논의한 것처럼 JavaScript 언어는 단일 스레드 모델을 사용한다는 것을 알아야 합니다. 그러나 JavaScript는 개발자에게 비동기 코드를 작성할 수 있는 기회도 제공합니다.

비동기 프로그래밍의 한계

이전 기사에서는 비동기 프로그래밍과 이를 사용해야 하는 경우에 대해 논의했습니다. 비동기 프로그래밍은 UI 인터페이스를 반응형(빠른 렌더링)으로 만들 수 있습니다. "코드 스케줄링"을 통해 시간을 요청해야 하는 코드가 이벤트 루프에 배치된 다음 나중에 실행되므로 UI가 먼저 렌더링되고 표시됩니다. 비동기 프로그래밍의 훌륭한 사용 사례는 AJAX 요청입니다. 요청에는 많은 시간이 걸릴 수 있으므로 클라이언트가 응답을 기다리는 동안 다른 코드를 실행할 수 있는 비동기식 요청을 사용할 수 있습니다.

그러나 이로 인해 문제가 발생합니다. 요청은 브라우저의 WEB API에 의해 처리되지만 다른 코드를 비동기식으로 만드는 방법은 무엇입니까? 예를 들어 성공 콜백의 코드가 CPU를 많이 사용하는 경우:

var result = performCPUIntensiveCalculation();
If performCPUIntensiveCalculation은 HTTP 요청이 아니라 차단 코드(예: 콘텐츠가 많은 for 루프)이므로 이벤트 루프를 제때 지울 수 없으며 브라우저의

UI

렌더링이 차단되면 페이지가 제때에 사용자에게 응답할 수 없습니다.

이는 비동기 함수가 JavaScript 언어의 단일 스레딩 제한 사항 중 일부만 해결할 수 있음을 의미합니다.

어떤 경우에는 setTimeout을 사용하여 장기 실행 계산을 차단할 수 있습니다. setTimeout을 사용하여 일시적으로 비동기 대기열에 넣어 페이지 속도를 높일 수 있습니다. 렌더링의. 예를 들어, 별도의 setTimeout 호출로 복잡한 계산을 일괄 처리하면 이를 이벤트 루프의 별도 "지점"에 배치하여 UI 렌더링/응답성에 대한 실행 시간을 얻을 수 있습니다.

숫자 배열의 평균을 계산하는 간단한 함수를 살펴보세요.

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

위 코드를 다시 작성하고 비동기성을 "시뮬레이트"하는 방법은 다음과 같습니다.

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

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

    function calculateSumAsync(i) {
        if (i <code>performCPUIntensiveCalculation</code> 不是一个HTTP请求而是一个阻塞代码(比如一个内容很多的for loop循环),就没有办法及时清空事件循环,浏览器的 <strong><em>UI</em></strong> 渲染就会被阻塞,页面无法及时响应给用户。<p>这意味着异步函数只能解决一小部分 JavaScript 语言单线程中的局限性问题。</p><p>在某些情况下,可以使用 <code>setTimeout</code> 对长时间运行的计算阻塞的,可以使用 <code>setTimeout</code>暂时放入异步队列中,从让页面得到更快的渲染。例如,通过在单独的 <code>setTimeout</code>이벤트 루프에 포함될 setTimeout 함수를 사용하세요. 계산의 각 단계가 추가됩니다. 각 계산 사이에는 브라우저가 렌더링할 수 있도록 다른 계산이 발생할 수 있는 충분한 시간이 있습니다. <strong></strong>Web Worker는 이 문제를 해결할 수 있습니다. </p><p>HTML5는 다음을 포함하여 많은 새로운 기능을 제공합니다. </p><p><img src="https://img.php.cn/upload/image/761/133/100/1607064795245272.png" title="1607064795245272.png" alt="JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오">SSE(이전 기사에서 WebSocket에 대해 설명하고 비교한 적이 있음) </p><p>Geolocation </p><p>애플리케이션 캐시</p><h2>로컬 저장소 </h2><p>드래그 앤 드롭</p>
  • Web Workers
  • Web Worker 개요
  • Web Worker의 역할은 JavaScript용 다중 스레드 환경을 생성하여 기본 스레드가 작업자 스레드를 생성하고 일부 작업을 후속 스레드 또는 스레드에 할당할 수 있도록 하는 것입니다. 달리다. 메인 스레드가 실행되는 동안 작업자 스레드는 백그라운드에서 실행되며 두 스레드는 서로 간섭하지 않습니다. 작업자 스레드가 계산 작업을 완료할 때까지 기다린 다음 결과를 기본 스레드에 반환합니다. 이것의 장점은 일부 컴퓨팅 집약적이거나 대기 시간이 긴 작업이 작업자 스레드에 의해 부담되고 기본 스레드(일반적으로 UI 상호 작용을 담당함)가 원활하고 차단되거나 속도가 느려지지 않는다는 것입니다.
  • "JavaScript는 단일 스레드 언어가 아닌가요?"라고 물을 수도 있습니다.
  • 사실 JavaScript는 스레딩 모델을 정의하지 않는 언어입니다. Web Worker는 JavaScript의 일부가 아니지만 JavaScript를 통해 액세스할 수 있는 브라우저 기능입니다. 역사적으로 대부분의 브라우저는 단일 스레드였으며(물론 이는 변경되었습니다) 대부분의 JavaScript 구현은 브라우저에서 이루어졌습니다. Web Worker는 Node.JS에서 구현되지 않습니다. Node.js에도 비슷한 개념의 클러스터와 child_process가 있습니다. 이 개념도 멀티스레드이지만 Web Worker와는 여전히 다릅니다. 사양에 언급된 웹 워커에는 세 가지 유형이 있다는 점에 주목할 필요가 있습니다.

Dedicated Workers(Dedicated Workers)

Shared Workers(Shared Workers)

Service Workers(서비스 워커)

Dedicated Workers

개인 작업자는 해당 작업자를 생성한 페이지에서만 액세스하고 통신할 수 있습니다. 브라우저가 지원하는 사항은 다음과 같습니다.

    JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

    Shared Workers

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

    JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

    Service workers

    Service Worker 功能:

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

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

    JavaScript Web Worker의 구성 요소와 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 Worker의 구성 요소와 5가지 사용 시나리오

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

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

消息的大小

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

  • 메시지 복사: 메시지는 직렬화, 복사, 전송된 다음 반대쪽에서 역직렬화됩니다. 페이지와 작업자는 동일한 인스턴스를 공유하지 않으므로 최종 결과는 각 패스마다 복사본이 생성되는 것입니다. 대부분의 브라우저는 JSON을 사용하여 양쪽 값을 인코딩하고 디코딩하므로 데이터의 디코딩 및 인코딩 작업은 다음과 같습니다. 메시지 전송 과정의 시간 오버헤드가 증가하게 됩니다. 메시지가 클수록 보내는 데 시간이 더 오래 걸립니다.
  • 메시지 전달: 이는 원래 보낸 사람이 메시지를 보낸 후에는 더 이상 해당 메시지를 사용할 수 없음을 의미합니다. 데이터 전송은 거의 즉각적입니다. 이 전송 방법의 한계는 ArrayBuffer 유형을 통해서만 전송할 수 있다는 것입니다.

Web Workers에서 사용할 수 있는 기능

JavaScript의 다중 스레드 특성으로 인해 Web Worker는 JavaScript 기능의 하위 집합에만 액세스할 수 있습니다. 다음은 그 기능 중 일부입니다.

Web Worker는 다중 스레드 특성으로 인해 JavaScript 기능의 하위 집합에만 액세스할 수 있습니다. 다음은 사용 가능한 기능 목록입니다.

  • navigator 객체
  • location 객체(읽기 전용)
  • MLHttpRequest
  • setTimeout()/clearTimeout() 및 setInterval()/clearInterval()
  • 애플리케이션 캐시
  • 사용 외부 스크립트를 가져오는 importScripts()importScripts() 导入外部脚本
  • 创建其他的 Web Workers

Web Workers 的局限性

遗憾的是,Web Workers 无法访问一些非常关键的 JavaScript 特性:

  • DOM(它会造成线程不安全)
  • window 对象
  • document  对象
  • parent 对象

这意味着 Web Worker 不能操作 DOM (因此也不能操作 UI)。有时这可能很棘手,但是一旦你了解了如何正确使用 Web Workers,你就会开始将它们作为单独的“计算机”使用,而所有 UI 更改都将发生在你的页面代码中。 Workers 将为你完成所有繁重的工作,然后一旦完成再把结果返回给 page 页面。

处理错误

和 JavaScript 代码一样,Web workers 里抛出的错误,你也需要进行处理。当 Worker 执行过程中如果遇到错误,会触发一个 ErrorEvent 事件。接口包含了三个有用的属性来帮忙排查问题:

  • filename  -  导致 Worker 的脚本名称
  • lineno - 发生错误的行号
  • message - 对错误的描述

例子如下:

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

在这里,可以看到我们创建了一个 worker 并开始侦听错误事件。

JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오

在 worker 内部(在 workerWithError.js 中),我们通过将未定义 x

다른 웹 작업자 만들기

웹 작업자의 제한

🎜안타깝게도 웹 작업자는 몇 가지 매우 중요한 JavaScript 기능에 액세스할 수 없습니다.🎜🎜🎜DOM( 스레드가 안전하지 않게 됩니다)🎜🎜window object🎜🎜document object🎜🎜parent object🎜🎜🎜 이는 Web Worker가 DOM(따라서 UI)을 조작할 수 없음을 의미합니다. 이는 때때로 까다로울 수 있지만 Web Workers를 올바르게 사용하는 방법을 이해하고 나면 이를 별도의 "컴퓨터"로 사용하기 시작하고 모든 UI 변경 사항이 페이지 코드에서 발생합니다. 작업자는 귀하를 위해 모든 힘든 작업을 수행한 다음 완료되면 결과를 페이지에 반환합니다. 🎜🎜오류 처리🎜🎜JavaScript 코드와 마찬가지로 웹 워커에서 발생한 오류도 처리해야 합니다. 작업자 실행 중에 오류가 발생하면 ErrorEvent 이벤트가 트리거됩니다. 인터페이스에는 문제 해결에 도움이 되는 세 가지 유용한 속성이 포함되어 있습니다. 🎜🎜🎜🎜filename🎜 - 작업자를 발생시킨 스크립트의 이름 🎜🎜🎜lineno🎜 - 오류가 발생한 줄 번호 🎜🎜🎜 메시지🎜 - 오류 🎜🎜🎜예제는 다음과 같습니다. 🎜🎜b9c86f918ebac5c56 16c530ca495704 .png🎜 🎜여기서 작업자를 생성하고 오류 이벤트 수신을 시작한 것을 볼 수 있습니다. 🎜🎜JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오 🎜🎜at 작업자 내부(workerWithError.js)에서 정의되지 않은 x에 2를 곱하여 예외를 생성합니다. 예외는 초기 스크립트로 전파된 다음 페이지를 통해 오류 이벤트를 모니터링하여 오류를 캡처합니다. 🎜🎜5 Good Web Workers 적용 사례🎜🎜지금까지 Web Worker의 장점과 한계를 나열했습니다. 이제 가장 강력한 사용 사례가 무엇인지 살펴보겠습니다. 🎜
  • Ray tracing: Ray tracing은 빛의 경로를 추적하여 픽셀 단위로 이미지를 생성하는 렌더링 기술입니다. 광선 추적은 CPU 집약적인 수학적 계산을 사용하여 빛의 경로를 시뮬레이션합니다. 아이디어는 반사, 굴절, 재료 등과 같은 일부 효과를 시뮬레이션하는 것입니다. UI 스레드 차단을 방지하기 위해 이 모든 계산 논리를 Web Worker에 추가할 수 있습니다. 더 좋은 점은 이미지 렌더링을 여러 작업자(및 여러 CPU) 간에 쉽게 분할할 수 있다는 것입니다. 다음은 Web Workers를 사용한 간단한 Ray Tracing 데모입니다(https://nerget.com/rayjs-mt/r...).
  • 암호화: 개인 데이터와 민감한 데이터에 대한 규제가 점점 엄격해짐에 따라 엔드투엔드 암호화가 점점 더 대중화되고 있습니다. 암호화는 매우 시간이 많이 걸리는 작업입니다. 특히 자주 암호화해야 하는 데이터가 많은 경우(예: 서버로 전송되기 전) 더욱 그렇습니다. 이는 DOM이나 기타 다른 것에 대한 액세스가 필요하지 않기 때문에 Web Worker를 사용하는 훌륭한 시나리오입니다. 이는 해당 작업을 수행하는 순수한 알고리즘입니다. Web Worker에서 작업하는 한 최종 사용자는 원활하게 작업을 수행할 수 있으며 경험에 영향을 미치지 않습니다.
  • 데이터 미리 가져오기(데이터 미리 가져오기): 웹 사이트 또는 웹 애플리케이션을 최적화하고 데이터 로딩 시간을 개선하려면 Web Workers를 사용하여 나중에 필요할 때 사용할 수 있도록 일부 데이터를 미리 로드하고 저장할 수 있습니다. 이 경우 웹 워커는 워커를 사용하지 않을 때와 달리 애플리케이션의 UI에 영향을 주지 않기 때문에 훌륭합니다.
  • 프로그레시브 웹 앱(프로그레시브 웹 애플리케이션): 이런 종류의 프로그레시브 웹 애플리케이션은 불안정한 사용자 네트워크 조건에서도 빠르게 로드할 수 있어야 합니다. 이는 데이터가 브라우저에 로컬로 저장되어야 함을 의미합니다. 이는 또한 IndexDB 또는 유사한 API가 작동하는 곳이기도 합니다. 일반적으로 클라이언트 측 저장소가 필요하지만 UI 렌더링 스레드를 차단하지 않고 사용하는 경우 Worker에서 작업을 수행해야 합니다. 그러나 IndexDB를 예로 들면 일부 비동기 API를 제공하므로 이를 호출하기 위해 웹 워커를 사용할 필요가 없습니다. 그러나 동기 API인 경우에는 워커에서 사용해야 합니다.
  • 맞춤법 검사: 기본 맞춤법 검사기의 작업 흐름은 다음과 같습니다. 프로그램은 철자가 정확한 단어 목록이 포함된 사전 파일을 읽습니다. 사전은 검색 트리로 구문 분석되어 실제 텍스트 검색을 더욱 효율적으로 만듭니다. 검사기에 단어가 제공되면 프로그램은 해당 단어가 미리 작성된 검색 트리에 존재하는지 확인합니다. 해당 단어가 트리에서 발견되지 않으면 대체 문자를 대체하고 사용자가 작성하려는 단어인 경우 유효한 단어인지 테스트하여 사용자에게 대체 철자를 제공할 수 있습니다. 이 모든 과정은 Web Worker에서 수행될 수 있으며, 사용자는 차단 없이 단어와 문장을 입력할 수 있습니다. Web Worker는 백그라운드에서 단어가 올바른지 확인하고 대체 단어를 제공합니다.

프로그래밍에 대해 더 자세히 알고 싶다면 php training 칼럼을 주목해주세요!

위 내용은 JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제