웹 어셈블리(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
- 코드 Rust 작성 (
lib.rs등) - WASM 컴파일 : 컴파일러를 통해
.wasm바이너리 파일 생성 - 브라우저 로딩 : JavaScript의
WebAssembly.instantiateStreaming()API를 통해 로드 및 인스턴스화 - 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 에 값을 넣어주거나, 활용해야 한다