본문 바로가기
React

React에서 Web Worker 사용하기

by 굿센스굿 2024. 12. 17.
반응형

React 애플리케이션이 복잡해지고 규모가 커지면 메인 스레드에서 처리해야 하는 작업의 양이 많아집니다. 이로 인해 성능 저하가 발생하고 사용자 경험이 떨어질 수 있습니다. 특히 무거운 연산이나 대량의 데이터를 처리해야 하는 경우 브라우저의 이벤트 루프가 차단되면서 UI가 멈추는 현상이 발생할 수 있습니다. 이러한 문제를 해결하기 위해 Web Worker를 사용할 수 있습니다.

Web Worker는 웹 애플리케이션의 메인 스레드와 별도로 실행되는 백그라운드 스레드입니다. 이를 통해 CPU를 많이 사용하는 작업을 메인 스레드와 분리해서 처리할 수 있어 애플리케이션의 성능을 향상시킬 수 있습니다.

이번 글에서는 React 애플리케이션에서 Web Worker를 사용하는 방법에 대해 알아보겠습니다.


Web Worker란?

Web Worker는 자바스크립트의 멀티스레딩을 지원하는 기능입니다. 이를 통해 CPU를 많이 소모하는 작업을 별도의 스레드에서 처리하고, 메인 스레드가 UI 업데이트나 이벤트 처리를 원활히 할 수 있도록 돕습니다.

Web Worker에는 다음과 같은 주요 특징이 있습니다:

  • 메인 스레드와 별도의 스레드에서 실행된다.
  • UI와는 상호작용할 수 없다. 즉, DOM을 직접 조작할 수 없습니다.
  • 메시지 기반의 통신을 통해 메인 스레드와 데이터를 주고받는다.
  • 비동기적으로 실행된다.

Web Worker는 크게 Dedicated Worker, Shared Worker, Service Worker 세 가지 종류로 나뉩니다. 이번 글에서는 React에서 가장 많이 사용하는 Dedicated Worker에 대해 다루겠습니다.


React에서 Web Worker 사용 준비하기

Web Worker는 브라우저의 기본 기능이므로 React 프로젝트에서도 별도의 패키지 설치 없이 사용할 수 있습니다. 하지만 Web Worker 파일을 모듈화하고 React 컴포넌트에서 사용하기 위해 몇 가지 설정이 필요합니다.

1. Web Worker 파일 생성

Web Worker는 별도의 자바스크립트 파일로 분리해야 합니다. 예를 들어, 다음과 같이 worker.js 파일을 생성합니다.

// worker.js
self.onmessage = function (e) {
  const { data } = e;
  const result = heavyTask(data);
  postMessage(result);
};

function heavyTask(input) {
  let result = 0;
  for (let i = 0; i < input; i++) {
    result += i;
  }
  return result;
}

위 코드는 onmessage 이벤트를 통해 메인 스레드로부터 데이터를 받고, heavyTask 함수에서 무거운 연산을 수행한 뒤 결과를 postMessage를 통해 메인 스레드에 반환합니다.

2. Web Worker를 React 컴포넌트에서 불러오기

React 컴포넌트에서 Web Worker를 사용하려면 Worker 인스턴스를 생성해야 합니다. 프로젝트에 따라 Web Worker 파일을 불러오는 방식은 다를 수 있지만, 일반적으로 WorkerLoader 또는 Blob URL을 사용합니다.

Blob URL을 사용하여 Worker 생성하기

먼저 worker.js 파일의 내용을 Blob URL로 변환합니다.

import React, { useEffect, useState } from 'react';

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

  useEffect(() => {
    const workerCode = `
      self.onmessage = function (e) {
        const { data } = e;
        let result = 0;
        for (let i = 0; i < data; i++) {
          result += i;
        }
        postMessage(result);
      };
    `;

    const blob = new Blob([workerCode], { type: 'application/javascript' });
    const worker = new Worker(URL.createObjectURL(blob));

    worker.onmessage = (e) => {
      setResult(e.data);
    };

    worker.postMessage(1000000000); // 무거운 작업 시작

    return () => {
      worker.terminate(); // 컴포넌트 언마운트 시 Worker 종료
    };
  }, []);

  return (
    <div>
      <h1>Web Worker 사용 예제</h1>
      <p>결과: {result}</p>
    </div>
  );
};

export default MyComponent;

코드 설명

  1. Worker 코드 정의: Worker의 동작을 Blob 형태로 변환하여 생성합니다.
  2. Worker 생성: new Worker()를 통해 Blob URL을 생성하고 Worker를 불러옵니다.
  3. 데이터 전송: postMessage()를 통해 Worker로 데이터를 전달합니다.
  4. 결과 수신: onmessage 이벤트를 통해 Worker로부터 결과를 받습니다.
  5. Worker 종료: 컴포넌트가 언마운트될 때 terminate()를 호출하여 Worker를 종료합니다.

Web Worker를 활용하는 예제

예제 1: 무거운 연산 처리

React 컴포넌트에서 Web Worker를 사용하면 CPU를 많이 소모하는 연산을 메인 스레드와 분리할 수 있습니다. 위의 예제에서는 0부터 10억까지의 합을 구하는 작업을 Web Worker에서 처리했습니다. 이렇게 하면 UI가 멈추는 현상을 방지할 수 있습니다.

예제 2: 이미지 프로세싱

Web Worker는 이미지 데이터를 처리하는 데도 유용하게 사용할 수 있습니다. 예를 들어, 픽셀 데이터를 조작하거나 필터를 적용하는 작업은 메인 스레드에서 실행하면 성능 저하를 일으킬 수 있습니다.


React에서 Web Worker 라이브러리 사용하기

React 프로젝트에서 Web Worker를 좀 더 쉽게 관리할 수 있도록 도와주는 라이브러리도 있습니다. 대표적으로 **workerize-loader**와 **comlink**가 있습니다.

1. workerize-loader

workerize-loader는 Web Worker를 모듈처럼 불러올 수 있도록 도와줍니다.

npm install --save-dev workerize-loader

사용 예제:

import Worker from 'workerize-loader!./worker';

const worker = new Worker();
worker.heavyTask(1000000000).then((result) => {
  console.log(result);
});

2. comlink

comlink는 Web Worker와의 통신을 추상화해주는 라이브러리입니다.

npm install comlink

사용 예제:

import { wrap } from 'comlink';

const worker = new Worker('./worker.js');
const workerApi = wrap(worker);

(async () => {
  const result = await workerApi.heavyTask(1000000000);
  console.log(result);
})();

결론

React 애플리케이션에서 Web Worker를 사용하면 무거운 작업을 메인 스레드와 분리하여 성능을 최적화할 수 있습니다. 특히 대량의 데이터 처리, 복잡한 연산, 이미지 프로세싱 등 CPU 사용량이 많은 작업에 Web Worker는 강력한 도구가 됩니다.

또한, workerize-loadercomlink와 같은 라이브러리를 사용하면 Web Worker를 더 쉽게 도입하고 사용할 수 있습니다. 프로젝트의 성능 병목이 발생하는 부분을 찾아 Web Worker를 활용해보세요! 😊

반응형

'React' 카테고리의 다른 글

React에서 Audio API 사용하기  (0) 2024.12.17
React에서 File API 사용하기  (0) 2024.12.17
React에서 IndexedDB 사용하기  (0) 2024.12.17
React에서 Cache API 사용하기  (0) 2024.12.17
React에서 Web Storage API 사용하기  (0) 2024.12.17