Web Worker와 활용방법

이수빈·2024년 3월 12일
2

Html, Css, JS

목록 보기
7/7
post-thumbnail

Web worker란?

  • 싱글스레드 기반 JS 한계점을 보안히기 위해 html5에서 제공하는 기능이다.

  • Web worker를 사용하지 않았을 때는 => UI 동작과 데이터핸들링이 순차적인 방식으로 처리가됨(싱글스레드), Web Worker를 사용해서 시간이 오래걸리는 작업 병렬처리 가능함.

  • JS엔진의 동작방식 => callstack이 스레드역할을 함.

  • 태스크큐 : 일반적인 이벤트 콜백 , 마이크로태스크큐 : Promise Callback, 애니메이션 프레임 : Request Animation 에 있는 태스크를 => callstack으로 옮겨서 순차적으로 처리

  • 이때 Web Worker를 생성하여 또 다른 스레드를 생성가능 => 메세지방식으로 데이터를 주고 받는다.

  • Web Worker 자체는 단순해서 메인 스레드에는 Web Worker로 로드할 URL을 넘겨주고 메시지를 주고받는 콜백을 등록하여 사용하면 됨

  • Web Worker로 사용될 스크립트에서도 마찬가지. 메시지 콜백만 등록하여 사용하면 된다.

사용방법

  • 작업자 스레드(main.js)에서 worker에서 실행할 스크립트의 url을 지정하여 생성자를 호출함
// main.js
const myWorker = new Worker("worker.js"); // 스크립트를 로드 

const first = document.querySelector('#number1'); //요소1
const second = document.querySelector('#number2'); //요소2

const result = document.querySelector('.result'); //결과

if (window.Worker) {
  const myWorker = new Worker("worker.js"); //worker load

  [first, second].forEach(input => {
    input.onchange = function() {
      myWorker.postMessage([first.value, second.value]);
      console.log('Message posted to worker');
    }
  }) //만약 input에 변화가 생기면 => worker에게 메세지를 송출함. 

  myWorker.onmessage = function(e) {
    result.textContent = e.data;
    console.log('Message received from worker');
  } // 메세지를 워커로 부터 받을때 동작하는 callback
} else {
  console.log('Your browser doesn\'t support web workers.');
} 
  • 메세지를 받으면 실행됨.
//worker.js

onmessage = function(e) {
  console.log('Worker: Message received from main script');
  const result = e.data[0] * e.data[1];
  if (isNaN(result)) {
    postMessage('Please write two numbers');
  } else {
    const workerResult = 'Result: ' + result;
    console.log('Worker: Posting message back to main script');
    postMessage(workerResult);
  }
}// postMessage를 받으면 Web Worker에서 해당로직을 처리 

언제 사용할까?

  • 첫 번째로, 화면 동작에 영향을 미치는 연산 동작, 즉, 바이너리 파일 핸들링이나 복잡한 계산이 필요한 경우에 유용

  • 두 번째로, 백그라운드에서 지속적인 작업을 해야 하거나 메인 스레드 영향을 미치지 않고 작업을 하는 경우에 유용하게 사용가능

  • 세 번째로는, 멀티 스레드로 개발했을 때 사용자 환경 개선에 도움이 되는 경우, 싱글 페이지 애플리케이션으로 개발되는 프로젝트라면, 사용했을 때 도움이 되는 부분이 있을 것으로 생각됨

  • 예를들어 프론트에서 엑셀 import나 export를 위해 data를 처리하는 과정은 메인스레드에서 진행하게 되면 오랜 시간이 걸리기 때문에 Web Worker를 사용한다.

  • React에서 사용시 custom hook으로 excel Import나 export 하는 파일에서 worker를 생성하고, 엑셀처리하는 로직을 worker에 넘기는 방식으로도 사용가능.

코드예시는 다음과 같다

  • Worker에서 처리할 비지니스 로직
// worker.js
onmessage = function (event) {
  console.log('Received message from the main thread:', event.data);

  // Perform some computation
  const result = event.data * 2;

  // Send the result back to the main thread
  postMessage(result);
};
  • Mount시 worker를 load후 onMessage Callback을 정의한다. => 데이터 처리

  • 버튼 이벤트 콜백 으로 postMessage 메소드 실행해서 메세지 방출

  • unmount시 clean up 작업 필수

// MyComponent.js
import React, { useState, useEffect } from 'react';

const MyComponent = () => {
  const [result, setResult] = useState(null);
  const [worker, setWorker] = useState(null);

  useEffect(() => {
    // Create a new web worker
    const myWorker = new Worker('worker.js');

    // Set up event listener for messages from the worker
    myWorker.onmessage = function (event) {
      console.log('Received result from worker:', event.data);
      setResult(event.data);
    };

    // Save the worker instance to state
    setWorker(myWorker);

    // Clean up the worker when the component unmounts
    return () => {
      myWorker.terminate();
    };
  }, []); // Run this effect only once when the component mounts

  const handleClick = () => {
    // Send a message to the worker
    if (worker) {
      worker.postMessage(5); // Send the number 5 to the worker
    }
  };

  return (
    <div>
      <p>Result from the worker: {result}</p>
      <button onClick={handleClick}>Calculate in Web Worker</button>
    </div>
  );
};

export default MyComponent;

이미지 ref) https://tech.kakao.com/2021/09/02/web-worker/

ref) mdn공식문서 : https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
https://tech.kakao.com/2021/09/02/web-worker/
https://medium.com/@ns-tech-learn/how-to-use-web-worker-in-react-1c8d7684253e

profile
응애 나 애기 개발자

0개의 댓글