본문 바로가기

개발이야기

React 고급 기술 익히기 - 9편: React와 WebAssembly(WASM) 연동하기

WebAssembly(WASM)는 웹 애플리케이션의 성능을 극대화할 수 있는 기술로,

React와 결합하면 보다 빠르고 강력한 웹 애플리케이션을 개발할 수 있습니다. Rust, C, C++ 등의 언어로 작성된 코드를 WebAssembly로 변환하여 React 애플리케이션에서 실행하면, 기존 JavaScript보다 훨씬 높은 성능을 발휘할 수 있습니다.

 

이번 글에서는 WebAssembly의 기본 개념, React에서 WebAssembly를 활용하는 방법, Rust와 WASM을 연동하는 실습을 다루고, Web Workers와 결합하여 병렬 연산을 최적화하는 방법까지 살펴봅니다. 🚀


1. WebAssembly(WASM)란?

WebAssembly(WASM)는 브라우저에서 실행 가능한 저수준의 이진 코드 포맷입니다. JavaScript보다 빠르게 실행되며, 고성능 연산이 필요한 애플리케이션(예: 이미지 처리, 비디오 렌더링, 게임 개발)에서 많이 사용됩니다.

 

WebAssembly의 주요 특징

  • 고성능: 네이티브 코드 수준의 실행 속도
  • 다중 언어 지원: Rust, C, C++ 등의 언어로 작성 가능
  • 브라우저 호환성: 모든 주요 브라우저에서 실행 가능
  • 보안성: 샌드박스 환경에서 실행되어 안전함

2. React에서 WebAssembly를 사용하는 이유

React는 컴포넌트 기반 아키텍처로 UI를 효율적으로 관리하지만, 무거운 연산을 수행할 때 성능 저하가 발생할 수 있습니다. WebAssembly를 활용하면 다음과 같은 이점을 얻을 수 있습니다.

 

복잡한 연산을 WASM으로 처리하여 성능 향상

Rust/C++ 등의 언어를 활용하여 연산 최적화

기존 React 코드와 쉽게 연동 가능


3. React + WebAssembly 실습 (Rust 활용)

3.1 Rust 환경 설정

먼저 Rust와 WebAssembly 개발 환경을 설정합니다.

Rust 및 wasm-pack 설치

# Rust 설치
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# wasm-pack 설치
cargo install wasm-pack

3.2 Rust 코드 작성 (숫자 연산 함수 만들기)

Rust로 WebAssembly 모듈을 만들고, 이를 React에서 호출해 보겠습니다.

새로운 프로젝트 생성 및 설정

cargo new --lib wasm_demo
cd wasm_demo

 

Cargo.toml 설정

[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

 

Rust 코드 작성 (src/lib.rs)

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

3.3 WebAssembly 빌드 및 React 연동

Rust 코드를 WebAssembly로 컴파일합니다.

wasm-pack build --target web

 

생성된 pkg/ 디렉터리 안에 WebAssembly 모듈이 포함됩니다.


4. React 프로젝트에서 WebAssembly 불러오기

4.1 React 프로젝트 설정

npx create-react-app wasm-app --template typescript
cd wasm-app

4.2 WebAssembly 모듈 불러오기

생성된 pkg/ 폴더를 src/wasm/ 디렉터리에 복사한 후, React에서 불러옵니다.

import React, { useEffect, useState } from "react";
import init, { add } from "./wasm/wasm_demo.js";

export default function App() {
  const [result, setResult] = useState<number | null>(null);

  useEffect(() => {
    init().then(() => {
      setResult(add(5, 10));
    });
  }, []);

  return (
    <div>
      <h1>React + WebAssembly</h1>
      <p>5 + 10 = {result}</p>
    </div>
  );
}

✅ init()을 실행하여 WebAssembly 모듈을 로드한 후, add(5,10)을 호출하여 결과를 React에서 표시합니다.


5. WebAssembly + Web Workers를 활용한 병렬 연산 최적화

WebAssembly는 Web Workers와 결합하여 더욱 강력한 성능을 발휘할 수 있습니다. Web Workers를 사용하면 브라우저의 메인 스레드를 차단하지 않고 백그라운드에서 연산을 실행할 수 있습니다.

5.1 Web Worker 파일 생성

먼저, Web Worker에서 WebAssembly 모듈을 실행하도록 설정합니다.

worker.js

self.importScripts("./wasm/wasm_demo.js");

self.onmessage = async (event) => {
  await wasm_bindgen("./wasm/wasm_demo_bg.wasm");
  const result = wasm_bindgen.add(event.data.a, event.data.b);
  postMessage(result);
};

5.2 React에서 Web Worker 실행

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

export default function App() {
  const [result, setResult] = useState<number | null>(null);

  useEffect(() => {
    const worker = new Worker(new URL("./worker.js", import.meta.url));
    worker.postMessage({ a: 5, b: 10 });
    worker.onmessage = (event) => setResult(event.data);
  }, []);

  return (
    <div>
      <h1>React + WebAssembly + Web Workers</h1>
      <p>5 + 10 = {result}</p>
    </div>
  );
}

✅ Web Worker를 활용하여 WebAssembly 연산을 실행하면 메인 스레드의 블로킹을 방지하고 성능을 향상할 수 있습니다.


결론

React와 WebAssembly(WASM)를 결합하면 고성능 웹 애플리케이션을 개발할 수 있습니다. 여기에 Web Workers를 활용하면 병렬 연산을 최적화하여 더욱 빠른 실행 속도를 확보할 수 있습니다.

728x90
반응형