Web Workers는 메인 스레드와 별도의 백그라운드 스레드에서 JavaScript를 실행하는 브라우저 API다. CPU 집약적인 작업을 메인 스레드에서 분리해 UI가 블로킹되지 않도록 한다.
Worker 종류
| 종류 | 특징 |
|---|
| Dedicated Worker | 단일 스크립트 전용 |
| Shared Worker | 여러 탭/창 공유 |
| Service Worker | 네트워크 프록시, 오프라인 |
기본 Dedicated Worker
javascript
// worker.js (워커 스크립트)
self.addEventListener('message', (event) => {
const { type, data } = event.data;
if (type === 'COMPUTE') {
// CPU 집약적 작업 (메인 스레드 블로킹 없이)
const result = heavyComputation(data);
self.postMessage({ type: 'RESULT', result });
}
});
function heavyComputation(data) {
// 예: 대용량 데이터 정렬, 암호화, 이미지 처리
return data.sort((a, b) => a - b);
}
javascript
// main.js (메인 스레드)
const worker = new Worker('/worker.js');
worker.postMessage({ type: 'COMPUTE', data: largeArray });
worker.addEventListener('message', (event) => {
const { type, result } = event.data;
if (type === 'RESULT') {
updateUI(result);
}
});
worker.addEventListener('error', (error) => {
console.error('Worker 오류:', error);
});
// 사용 후 종료
worker.terminate();
Comlink: 워커를 프록시처럼 사용
javascript
// worker.js
import * as Comlink from 'comlink';
const api = {
async processData(data) {
return heavyComputation(data);
},
async fibonacci(n) {
if (n <= 1) return n;
return (await api.fibonacci(n - 1)) + (await api.fibonacci(n - 2));
},
};
Comlink.expose(api);
// main.js
import * as Comlink from 'comlink';
const worker = new Worker('/worker.js', { type: 'module' });
const api = Comlink.wrap(worker);
// 마치 일반 함수처럼 호출 (내부적으로 postMessage)
const result = await api.processData(largeData);
const fib = await api.fibonacci(40);
SharedArrayBuffer와 Atomics
javascript
// 공유 메모리 (Cross-Origin-Opener-Policy 헤더 필요)
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
// 워커와 공유 메모리 공유
worker.postMessage({ sharedBuffer });
// 원자적 연산으로 동기화
Atomics.store(sharedArray, 0, 42);
const value = Atomics.load(sharedArray, 0);
Atomics.add(sharedArray, 0, 10);
관련 개념