싱글스레드 기반 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
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.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