🏆

WASM을 웹의 1급 언어로 만들기

JS glue 없이 Web API를 직접 호출하는 Component Model

WebAssembly가 웹에서 2급 시민으로 취급되는 현재의 문제와, Mozilla의 Component Model이 이를 어떻게 해결하려는지를 다룹니다.

구조 다이어그램

Before vs After
현재: WASM = 2급 시민
📝
Rust / C++
📦
.wasm
JS Glue Code
embind / wasm-bindgen
🌐
Web API
-45% 성능
미래: Component Model = 1급 시민
📝
Rust / C++
🧩
Component (.wasm)
WIT 인터페이스 포함
🌐
Web API 직접 호출
JS glue 불필요!
WIT 인터페이스 예시
WIT 선언:
component {
  import std:web/console;
}
Rust에서 사용:
use std_web::console;
console::log("hello, world");
표준화 타임라인
2017 WASM 출시 현재: Mozilla + Google 표준화 중 실험: Jco, Wasmtime 미래: 브라우저 네이티브 지원 (수년 소요)

동작 흐름

1

현재: WASM은 WebAssembly.instantiateStreaming() 등 JS API로 수동 로딩 필요

2

현재: DOM, console 등 Web API에 직접 접근 불가 — JS glue code가 브릿지

3

현재: 언어마다 별도 바인딩 도구, rustc --target=wasm 결과물이 브라우저에서 바로 안 됨

4

Component Model: WIT(Interface Description Language)로 필요한 Web API 선언

5

Component Model: 브라우저가 <script type="module" src="component.wasm">으로 직접 로드

6

Component Model: JS에서 import { fn } from "lib.wasm" 형태로 하이브리드 사용 가능

7

결과: JS glue code 완전 제거 → 45% 성능 오버헤드 해소, 툴체인 통일

장점

  • JS glue code 완전 제거 — 45% DOM 성능 오버헤드 해소
  • WASM을 JS처럼 <script> 태그로 직접 로드 가능
  • 언어별 툴체인 통일 — 표준 컴파일러로 바로 브라우저 실행
  • WIT로 타입 안전한 Web API 인터페이스 선언
  • JS와 하이브리드 사용 가능 — 점진적 도입 가능
  • 브라우저 밖에서도 실행 (Wasmtime) — 웹과 서버 코드 재사용

단점

  • 아직 표준화 진행 중 — 프로덕션 사용은 시기상조
  • 사양 변동이 잦아 툴링 churn 발생
  • Polyfill/기능 감지 어려움 — JS 브릿지의 유연성 상실 가능
  • Component Model 자체가 새로운 복잡성 도입 (WIT 학습 필요)
  • WebGL2/WebGPU에서는 JS shim 비용이 이미 미미
  • 메모리 관리 미해결 — Wasm GC 제안이 DOM 참조에 필요한지 불분명

사용 사례

DOM 집약적 WASM 앱 — glue 없이 직접 DOM 조작 Rust/C++ 웹 프레임워크가 JS 없이 독립적으로 동작 다국어 컴포넌트 조합 — Rust 이미지 처리 + Go 네트워크 + JS UI 모바일 OS 폐쇄성에 대한 대안 — 네이티브 앱 수준의 웹 앱 WASM Registry를 통한 컴포넌트 재사용 생태계