⚙️

WebAssembly(WASM)는 어떻게 동작하나?

C++/Rust/Zig 코드를 브라우저에서 네이티브 속도로 실행

WebAssembly(WASM)는 C++, Rust, Zig 등 정적 타입 언어로 작성된 코드를 브라우저에서 네이티브에 가까운 속도로 실행하는 바이트코드 포맷입니다.

구조 다이어그램

📝
소스 코드
C / C++ Rust Zig Go (tinygo)
① 컴파일 Emscripten / wasm-pack / zig build
📦
npm 패키지
.wasm (바이트코드) JS/TS 래퍼 (glue) TypeScript 타입
② 번들 Vite / webpack
🌐
브라우저
WASM Runtime
WebAssembly.compile() WebAssembly.instantiate() JS ↔ WASM 호출
WASM 전달 방식:
A 별도 .wasm 파일 → fetch()로 로드 → 캐싱 가능
B base64 인라인 → JS 번들에 내장 → 추가 요청 없음 (ghostty-web 방식)
핵심 포인트
  • JavaScript는 WASM으로 컴파일 불가 — WASM은 정적 타입 언어 전용 컴파일 타겟
  • WASM은 DOM에 직접 접근 불가 — JS 래퍼(glue code)가 브릿지 역할
  • 브라우저의 샌드박스 안에서 실행 — 네이티브 앱과 동일한 보안
  • 실제 사례: Figma(C++), FFmpeg.wasm(C), Ghostty Web(Zig), Photoshop(C++)

동작 흐름

1

소스 코드 작성 (C++, Rust, Zig 등 정적 타입 언어)

2

언어별 WASM 컴파일러로 .wasm 바이트코드 생성 (Emscripten, wasm-pack, zig build 등)

3

JS/TS 래퍼(glue code) 작성 — WASM 함수를 JS API로 노출, Web API 브릿지 역할

4

npm 패키지로 배포 (예: npm install ghostty-web). WASM은 base64 인라인 또는 별도 .wasm 파일로 번들

5

프론트엔드 빌드 도구(Vite, webpack)가 패키지를 번들링. dynamic import()로 WASM 모듈 로드

6

브라우저가 WebAssembly.compile() → instantiate()로 바이트코드 컴파일 및 인스턴스 생성

7

JS에서 WASM 함수 호출 ↔ WASM에서 JS 콜백 호출 — 양방향 통신으로 연동

장점

  • 네이티브에 가까운 실행 속도 (JS 대비 10~100배 빠른 연산)
  • C++/Rust 등 기존 코드베이스 재활용 (30년 된 C++ 코드도 웹에서 실행)
  • 샌드박스 실행 (브라우저 보안 모델 그대로 적용)
  • 언어에 독립적 (컴파일만 되면 어떤 언어든 OK)
  • 서버 부하 감소 (무거운 연산을 클라이언트에서 처리)

단점

  • DOM/Web API 직접 접근 불가 — 반드시 JS glue code 경유
  • 빌드 환경 복잡 (Emscripten/wasm-pack 설치, 크로스 컴파일)
  • 초기 로드 시간 (.wasm 다운로드 + 컴파일 오버헤드)
  • 디버깅 어려움 (소스맵 미성숙, console.log 불가)
  • 메모리 관리가 수동 (GC 없음), JS↔WASM 데이터 교환에 직렬화 비용

사용 사례

Figma (C++ 2D 렌더링 엔진을 웹에서 네이티브 속도로) FFmpeg.wasm (서버 없이 브라우저에서 동영상 변환) Ghostty Web (Zig 터미널 파서를 웹 터미널에 사용) Google Earth Web (C++ 3D 지도 렌더링) AutoCAD Web (C++ CAD 엔진 30년 코드 재활용) Photoshop Web (C++ 이미지 처리 엔진)