Web Worker는 브라우저의 메인 스레드와 별도로 동작하는 백그라운드 스레드로, 무거운 연산 작업을 메인 스레드의 차단 없이 처리할 수 있게 해줍니다. 메시지 기반 통신을 통해 메인 스레드와 데이터를 주고받으며, 데이터는 복사되어 전달됩니다.
기본 구조 살펴보기
간단한 덧셈 계산기를 통해 Web Worker의 동작 방식을 이해해보겠습니다. 사용자가 입력한 두 숫자를 워커 스레드에서 계산하고 결과를 반환하는 예제입니다.
메인 페이지 구성
HTML 파일에서는 워커 인스턴스를 생성하고, 사용자 입력을 수집하여 워커로 전송합니다. 계산이 완료되면 워커에서 보낸 결과를 화면에 표시합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Web Worker 예제</title>
</head>
<body>
<h3>두 숫자의 합 계산 (Web Worker 활용)</h3>
<div class="calculator">
<input type="number" id="operandA" value="10" placeholder="첫 번째 숫자">
<span>+</span>
<input type="number" id="operandB" value="20" placeholder="두 번째 숫자">
<button id="triggerBtn">계산 실행</button>
<input type="text" id="outputField" readonly placeholder="결과">
</div>
<script>
// 워커 스크립트 로드
const calcWorker = new Worker('calc-worker.js');
// DOM 요소 참조
const firstInput = document.getElementById('operandA');
const secondInput = document.getElementById('operandB');
const executeBtn = document.getElementById('triggerBtn');
const resultDisplay = document.getElementById('outputField');
// 계산 버튼 클릭 시 워커에 작업 요청
executeBtn.addEventListener('click', () => {
const x = parseFloat(firstInput.value) || 0;
const y = parseFloat(secondInput.value) || 0;
console.log('메인 스레드: 계산 요청 전송');
calcWorker.postMessage({
operation: 'sum',
payload: { augend: x, addend: y }
});
});
// 워커로부터 결과 수신
calcWorker.addEventListener('message', (evt) => {
console.log('메인 스레드: 결과 수신', evt.data);
const { operation, payload } = evt.data;
if (operation === 'sum') {
resultDisplay.value = payload;
}
});
</script>
</body>
</html>
워커 스크립트 구현
별도 파일로 분리된 워커 스크립트는 메시지를 대기하다가 요청이 오면 계산을 수행하고 결과를 다시 메인 스레드로 전송합니다.
// calc-worker.js
self.addEventListener('message', function(evt) {
console.log('워커 스레드: 요청 수신', evt.data);
const { operation, payload } = evt.data;
if (operation === 'sum') {
const computationResult = payload.augend + payload.addend;
// 메인 스레드로 결과 반환
self.postMessage({
operation: 'sum',
payload: computationResult
});
}
});
동작 흐름 정리
이 예제에서 메인 스레드와 워커 스레드 간의 상호작용은 다음과 같이 진행됩니다:
- 페이지 로드 시
new Worker()로 워커 인스턴스 생성 - 사용자가 버튼 클릭 →
postMessage()로 계산 요청 전송 - 워커의
message이벤트 핸들러에서 요청 수신 및 계산 수행 - 워커가
postMessage()로 결과를 메인 스레드에 전달 - 메인 스레드의
message이벤트 핸들러에서 결과 수신 및 화면 갱신
활용 시 고려사항
Web Worker는 DOM에 직접 접근할 수 없으므로, UI 업데이트가 필요한 경우 반드시 메인 스레드로 결과를 전송해야 합니다. 또한 워커는 importScripts()를 통해 외부 라이브러리를 로드할 수 있으며, 복잡한 알고리즘이나 대용량 데이터 처리에 적합합니다.