웹 어셈블리(WebAssembly) - YooByWk/YooByWk.github.io GitHub Wiki

웹 어셈블리(WebAssembly)

개요

WebAssembly 란 웹 브라우저에서 네이티브에 가까운 성능으로 코드를 실행할 수 있게 해주는 바이너리 명령어 형식이자, 스택 기반 가상 머신을 위한 개방형 웹 표준.

  • 컴파일 타깃 : JavaScript 외에도 C,C++,Rust,Go 등 다양한 언어로 작성된 프로그램을 웹에서 실행하기 위한 타깃
  • 파일 형식 : CPU 처리에 용이한 저수준 바이너리 형식

등장 배경 및 성능 우위

등장 배경

  • JavaScript 성능 한계: 동적 타입 언어인 JS는 JIT 컴파일에도 불구하고, 물리 시뮬레이션, 복잡한 암호화 등 CPU 집약적 작업에서 근본적인 오버헤드가 발생.
  • W3C 웹 표준: 주요 브라우저 벤더들이 합의한 표준으로, 모든 모던 브라우저에서 일관적인 성능을 보장.

성능 우위

WASM은 JS 대비 다음과 같은 우위를 가진다

  • 바이너리 형식 (빠른 로딩)

    텍스트 파싱 과정이 거의 없어, 다운로드 후 WASM 엔진의 로딩 및 초기화 시간 단축.

  • AOT 컴파일에 유리:

    WASM은 정적 타입 기반의 저수준 코드로, 브라우저 엔진이 코드를 실행하기 전 AOT (Ahead-of-Time) 방식으로 빠르게 최적화된 기계어로 변환.

    이는 런타임에 타입 추론이 필요한 JS의 오버헤드 감소로 이어진다.

내부 구조 및 동작

실행 아키텍처

스택 기반 VM : WASM 명령어는 CPU 레지스터 대신 스택을 중심으로 연산을 수행

선형 메모리 : WASM 모듈은 호스트 환경(브라우저)에게 할당 받은 연속된 바이트 배열을 사용한다. 이는 WASM의 샌드박스 보안의 기반이 되며, 외부 메모리 접근 통제

실행 과정

Rust

  1. 코드 Rust 작성 (lib.rs 등)
  2. WASM 컴파일 : 컴파일러를 통해 .wasm 바이너리 파일 생성
  3. 브라우저 로딩 : JavaScript의 WebAssembly.instantiateStreaming() API를 통해 로드 및 인스턴스화
  4. JS 상호작용 : JS가 WASM 인스턴스의 exports 를 호출하여 로직 실행 및 결과 반환 (wasm은 DOM 접근 불가)
# wasm-pack 설치 (개발환경 구성)
cargo install wasm-pack

# WASM 패키징 (Web 환경 타깃)
wasm-pack build --target web
# 결과: pkg/ 디렉토리에 .wasm 바이너리 및 JS Glue 파일 생성

오해와 사실

1. JavaScript를 대체한다.

JS를 보완한다.

WASM은 연산에 특화되며, API 접근 및 DOM 조작은 여전히 JS를 통해 이루어져야 한다. (WASM은 DOM 조작이 불가하다)

2. JS보다 항상 빠르다.

CPU 집약적 연산에 빠르다.

작은 모듈은 초기 로딩 오버헤드 때문에 JS의 JIT 컴파일이 더 빠를 수 있다.

즉 복잡한 연산에서 효율이 극대화된다.

3. 브라우저에서만 사용된다.

범용 런타임입니다.

WASI (WebAssembly System Interface) 표준을 통해 Node.js, 서버리스, CLI 등 비(非) 브라우저 환경에서도 사용 가능.

여담

  • 탈 중앙화 연결성 : 고성능 연산 + 데이터 프라이버시가 만족되어야 하는 경우에도 사용 가능
  • JS-WASM 호출 비용 고려 : 호출 횟수는 최소화되어야 한다. (상호간 호출 비용이 비쌈)
  • 디버깅 복잡성 : 바이너리 코드이므로 디버깅이 쉽지 않다
  • DOM 접근 불가 : JS를 통해 여전히 DOM 에 값을 넣어주거나, 활용해야 한다

연관 링크

MDN - 웹 어셈블리

삼성 테크 블로그 - 웹 어셈블리