본문 바로가기

WebAssembly 기초

WebAssembly의 바이너리 실행 모델과 JavaScript 연동을 이해하고 C 함수를 Wasm으로 빌드해 브라우저에서 호출합니다.

앞 절의 비동기 로드와 배포 파일 개념을 바탕으로, 이번에는 소스를 만드는 단계와 브라우저에서 모듈을 초기화해 호출하는 단계를 구별합니다. 작은 덧셈은 호출 계약을 익히는 예제이며 성능 비교 자료는 아닙니다.

WebAssembly 빌드·호출 데이터 흐름 — 상태 추적

본문 add.c→emcc 산출물→await factory→_add(10,20)→30에서 생성 파일과 호출 준비 상태가 달라진다. 다운로드와 인스턴스 준비/호출 성공을 구분한다.

add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다

EMSCRIPTEN EXAMPLE

add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다

이 절은 Emscripten의 MODULARIZE·EXPORT_ES6 경로를 사용합니다. add.js와 add.wasm을 함께 제공하고, JavaScript wrapper가 로드·초기화를 마친 뒤 함수를 호출합니다.

산출물생성과초기화뒤호출을구별한다6노드5순서관계. 첫영역은C소스→emcc→JS/Wasm산출물이며둘째영역은브라우저awaitfactory→wrapper_add호출→성공시30이다. 실패시catch이며다운로드만으로호출성공·성능우위를보증하지않는다. 원760SVG전체bytes는지원숨김보존이고newmobile는동일두영역과순서다.빌드 시점브라우저 실행C 소스 add.cemcc 빌드_add 내보내기add.js + add.wasmHTTP로 함께 제공await factory인스턴스 준비module._add(10, 20)함수 호출성공 결과 30성능 측정 아님
산출물생성과초기화뒤호출을구별한다6노드5순서관계. 첫영역은C소스→emcc→JS/Wasm산출물이며둘째영역은브라우저awaitfactory→wrapper_add호출→성공시30이다. 실패시catch이며다운로드만으로호출성공·성능우위를보증하지않는다. 원760SVG전체bytes는지원숨김보존이고newmobile는동일두영역과순서다.빌드브라우저C 소스 add.cemcc 빌드_add 내보내기add.js + add.wasmHTTP로 함께 제공await factory인스턴스 준비module._add(10, 20) 호출성공 결과 30성능 측정 아님
add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다C 소스를 emcc로 빌드해 add.js와 add.wasm을 만들고 HTTP 제공 후 factory를 기다려 module._add(10,20)을 호출합니다. 성공 시 예상값은 30입니다.1. add.cint add(int a, int b)2. emcc 빌드_add 내보내기 지정3. add.js + add.wasmHTTP로 함께 제공4. factory 초기화await createAddModule()5. JS에서 호출module._add(10, 20)브라우저예상 결과: 30

빌드 산출물 · C → JS와 Wasm

add.c → emcc
add.js · add.wasm

add.js는 ES module의 default factory를 내보냅니다. HTML과 index.js는 따로 준비하며, 이 예제는 생성 파일들을 같은 경로에서 HTTP로 제공합니다.

브라우저에서 초기화 후 호출

const module =
  await createAddModule();
module._add(10, 20); // 30

초기화 Promise가 완료된 뒤 JS wrapper의 _add를 호출합니다. 로드·초기화·실행 실패는 예제의 catch에서 처리합니다.

raw WebAssembly 경로와 구별

WebAssembly.instantiate를 직접 사용하는 경우의 imports·exports 이름은 실제 모듈 계약을 따라야 합니다. 이 절의 module._add는 생성된 Emscripten wrapper의 이름입니다.

작은 덧셈 예제로 성능을 단정하지 않기

30은 두 정수 덧셈의 성공 시 예상값입니다. 이 흐름은 API 사용법을 보여주며, 툴체인 빌드나 성능 측정을 수행한 결과는 아닙니다. 큰 데이터의 메모리 전달은 별도 인터페이스를 설계합니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
관계도의 보충 설명
원도표의 전체 관계·조건·설명
구분내용
도표 이름산출물 생성과 초기화 뒤 호출을 구별한다
전체 관계·조건 설명노드 6개·순서 관계 5개다. 첫 영역은 C 소스→emcc→JS/Wasm 산출물이며 둘째 영역은 브라우저 await factory→wrapper _add 호출→성공 시 30이다. 실패 시 catch이며 다운로드만으로 호출 성공·성능 우위를 보증하지 않는다. 원 760 SVG 전체 bytes는 지원용 숨김 자료로 보존하고 new mobile은 동일한 두 영역과 순서를 따른다.
원도표 설명30은 두 정수 덧셈의 성공 시 예상값입니다. 이 흐름은 API 사용법을 보여 주며, 툴체인 빌드나 성능 측정을 수행한 결과는 아닙니다. 큰 데이터의 메모리 전달은 별도 인터페이스를 설계합니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
C 소스 빌드입력: add.c / 산출: JS glue + wasmemcc가 add.js와 wasm을 준비한다브라우저가 C 소스를 직접 실행하지 않는다
factory 준비모듈: 준비 중→사용 가능 / 호출: 아직 실행 안 함모듈 factory의 완료를 await한다비동기 초기화 뒤에 export를 사용한다
add 실행인수: 10,20 / 반환: 30_add(10,20)을 호출한다결과 계약을 확인하며 속도 우위를 추정하지 않는다

WebAssembly 빌드·호출 데이터 흐름 — 상태 추적

본문 add.c→emcc 산출물→await factory→_add(10,20)→30에서 생성 파일과 호출 준비 상태가 달라진다. 다운로드와 인스턴스 준비/호출 성공을 구분한다.

add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다

EMSCRIPTEN EXAMPLE

add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다

이 절은 Emscripten의 MODULARIZE·EXPORT_ES6 경로를 사용합니다. add.js와 add.wasm을 함께 제공하고, JavaScript wrapper가 로드·초기화를 마친 뒤 함수를 호출합니다.

산출물생성과초기화뒤호출을구별한다6노드5순서관계. 첫영역은C소스→emcc→JS/Wasm산출물이며둘째영역은브라우저awaitfactory→wrapper_add호출→성공시30이다. 실패시catch이며다운로드만으로호출성공·성능우위를보증하지않는다. 원760SVG전체bytes는지원숨김보존이고newmobile는동일두영역과순서다.빌드 시점브라우저 실행C 소스 add.cemcc 빌드_add 내보내기add.js + add.wasmHTTP로 함께 제공await factory인스턴스 준비module._add(10, 20)함수 호출성공 결과 30성능 측정 아님
산출물생성과초기화뒤호출을구별한다6노드5순서관계. 첫영역은C소스→emcc→JS/Wasm산출물이며둘째영역은브라우저awaitfactory→wrapper_add호출→성공시30이다. 실패시catch이며다운로드만으로호출성공·성능우위를보증하지않는다. 원760SVG전체bytes는지원숨김보존이고newmobile는동일두영역과순서다.빌드브라우저C 소스 add.cemcc 빌드_add 내보내기add.js + add.wasmHTTP로 함께 제공await factory인스턴스 준비module._add(10, 20) 호출성공 결과 30성능 측정 아님
add.c를 빌드한 JS factory를 기다린 뒤 _add를 호출합니다C 소스를 emcc로 빌드해 add.js와 add.wasm을 만들고 HTTP 제공 후 factory를 기다려 module._add(10,20)을 호출합니다. 성공 시 예상값은 30입니다.1. add.cint add(int a, int b)2. emcc 빌드_add 내보내기 지정3. add.js + add.wasmHTTP로 함께 제공4. factory 초기화await createAddModule()5. JS에서 호출module._add(10, 20)브라우저예상 결과: 30

빌드 산출물 · C → JS와 Wasm

add.c → emcc
add.js · add.wasm

add.js는 ES module의 default factory를 내보냅니다. HTML과 index.js는 따로 준비하며, 이 예제는 생성 파일들을 같은 경로에서 HTTP로 제공합니다.

브라우저에서 초기화 후 호출

const module =
  await createAddModule();
module._add(10, 20); // 30

초기화 Promise가 완료된 뒤 JS wrapper의 _add를 호출합니다. 로드·초기화·실행 실패는 예제의 catch에서 처리합니다.

raw WebAssembly 경로와 구별

WebAssembly.instantiate를 직접 사용하는 경우의 imports·exports 이름은 실제 모듈 계약을 따라야 합니다. 이 절의 module._add는 생성된 Emscripten wrapper의 이름입니다.

작은 덧셈 예제로 성능을 단정하지 않기

30은 두 정수 덧셈의 성공 시 예상값입니다. 이 흐름은 API 사용법을 보여주며, 툴체인 빌드나 성능 측정을 수행한 결과는 아닙니다. 큰 데이터의 메모리 전달은 별도 인터페이스를 설계합니다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.

관계도의 보충 설명

원도표의 전체 관계·조건·설명
구분내용
도표 이름산출물 생성과 초기화 뒤 호출을 구별한다
전체 관계·조건 설명노드 6개·순서 관계 5개다. 첫 영역은 C 소스→emcc→JS/Wasm 산출물이며 둘째 영역은 브라우저 await factory→wrapper _add 호출→성공 시 30이다. 실패 시 catch이며 다운로드만으로 호출 성공·성능 우위를 보증하지 않는다. 원 760 SVG 전체 bytes는 지원용 숨김 자료로 보존하고 new mobile은 동일한 두 영역과 순서를 따른다.
원도표 설명30은 두 정수 덧셈의 성공 시 예상값입니다. 이 흐름은 API 사용법을 보여 주며, 툴체인 빌드나 성능 측정을 수행한 결과는 아닙니다. 큰 데이터의 메모리 전달은 별도 인터페이스를 설계합니다.
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
C 소스 빌드입력: add.c / 산출: JS glue + wasmemcc가 add.js와 wasm을 준비한다브라우저가 C 소스를 직접 실행하지 않는다
factory 준비모듈: 준비 중→사용 가능 / 호출: 아직 실행 안 함모듈 factory의 완료를 await한다비동기 초기화 뒤에 export를 사용한다
add 실행인수: 10,20 / 반환: 30_add(10,20)을 호출한다결과 계약을 확인하며 속도 우위를 추정하지 않는다

기존 웹 애플리케이션의 핵심 언어인 JavaScript는 동적인 웹 페이지를 만드는 데 매우 강력하고 유연합니다.

다만 CPU 집약적인 작업(3D 게임, 비디오 편집, 이미지 처리, 과학 계산)에서는 성능 한계가 드러날 때가 있습니다.

동적 타입, JIT 최적화, 가비지 컬렉션, 메인 스레드 UI 처리와 맞물려 무거운 반복 계산에서 예측 가능한 성능을 확보하기 어려울 수 있기 때문입니다.

이 문제를 해결하기 위해 등장한 기술이 WebAssembly (Wasm)입니다.

WebAssembly는 웹에서 고성능 애플리케이션 실행을 가능하게 하고, 연산량이 큰 애플리케이션도 원활히 동작할 수 있도록 돕습니다.

이번 장에서는 WebAssembly가 무엇인지, 왜 필요한지, 어떻게 동작하는지 기본 개념을 정리합니다.

핵심 목적은 웹이 문서 중심 플랫폼을 넘어 고성능 실행 환경으로 확장되는 흐름을 이해하는 것입니다.


WebAssembly (Wasm)이란?

WebAssembly는 현대 웹 브라우저와 다양한 런타임에서 실행되도록 설계된 컴팩트한 이진 명령 형식이자 저수준 컴파일 대상입니다.

사람이 주로 직접 작성하는 언어라기보다 C, C++, Rust 같은 언어의 결과물을 웹에서 실행하기 위한 형식에 가깝고, JavaScript와 함께 동작할 수 있도록 설계되었습니다.

  • 컴파일 대상: C, C++, Rust와 같은 고성능 언어들을 WebAssembly 모듈로 컴파일할 수 있습니다.
  • 이진 형식: 텍스트 형식이 아닌 컴팩트한 이진 형식으로 배포되어 네트워크 전송 및 파싱 속도가 빠릅니다.
  • 샌드박스 실행: 브라우저의 WebAssembly 엔진에서 검증된 뒤 격리된 실행 환경 안에서 동작합니다.
  • JavaScript와 상호 운용: WebAssembly 모듈은 JavaScript에서 호출되고, JavaScript도 WebAssembly 모듈이 제공하는 함수를 사용할 수 있습니다.

WebAssembly의 필요성

  • 성능 향상: CPU 집약적인 계산을 네이티브에 가까운 성능으로 실행하도록 설계되었습니다. 모든 JavaScript 코드보다 항상 빠른 것은 아니지만, 게임, 이미지/비디오 편집, CAD, VR/AR, 과학 시뮬레이션처럼 계산량이 큰 작업에 유리합니다.
  • 기존 코드 재활용: C, C++, Rust 등으로 작성된 기존의 고성능 라이브러리나 애플리케이션을 웹으로 쉽게 포팅하여 재활용할 수 있습니다. 웹 개발자들이 새로운 언어를 배우지 않고도 기존의 전문 지식을 활용할 수 있게 합니다.
  • 성능 평가: JavaScript와 Wasm 모두 엔진·컴파일·메모리·입력 크기의 영향을 받습니다. 초기 로드와 반복 호출, 데이터 전달 비용을 포함해 같은 작업을 비교해야 성능 이득이 있는지 판단할 수 있습니다.
  • 메인 스레드 부담 감소: Web Workers와 함께 사용하면 메인 스레드의 부담을 줄여 UI의 반응성을 높일 수 있습니다.
  • 보안: 안전한 샌드박스 환경에서 실행됩니다.

WebAssembly vs. JavaScript

특징WebAssemblyJavaScript
타입정적 타입 (컴파일 시 타입 결정)동적 타입 (런타임 시 타입 결정)
실행 속도계산 집약 작업에서 예측 가능한 고성능에 유리일반 웹 로직에 최적화, 무거운 계산은 부담
용량컴팩트한 이진 형식, 파싱/전송 효율에 유리텍스트 기반, 파싱과 최적화 과정 필요
개발 언어C, C++, Rust 등 여러 언어의 컴파일 대상JavaScript 자체
주 사용처고성능 연산, 게임, 이미지 처리, 비디오 인코딩 등DOM 조작, UI 상호작용, 일반적인 웹 로직 처리
상호 운용JavaScript와 상호 호출 가능WebAssembly 호출 가능

핵심: WebAssembly는 JavaScript를 대체하는 것이 아니라, JavaScript가 잘 하지 못하는 고성능 연산 부분을 보완하는 동반자입니다.

대부분의 웹 애플리케이션에서는 여전히 JavaScript가 UI와 사용자 상호작용을 담당하고, WebAssembly는 필요한 고성능 모듈을 담당하는 방식으로 사용됩니다.

Web Worker는 작업을 수행할 위치를 나누는 수단이고 Wasm은 실행 코드의 형식입니다. 둘은 대안만이 아니라 함께 사용할 수 있는 선택입니다. DOM과 사용자 입력을 연결하는 JavaScript 코드, JS↔Wasm 값 전달, 오류 대체 경로도 구현 범위에 남습니다.

예시

실측 대신 비교 연습의 조건을 정합니다. 한 묶음 처리에 JavaScript는 12ms, Wasm은 최초 초기화 18ms에 묶음당 계산 4ms와 전달 3ms가 필요하며 초기화는 한 번만 한다고 가정합니다. 첫 묶음은 Wasm 18+4+3=25ms라 12ms보다 깁니다. 3묶음은 18+3×7=39ms 대 36ms, 4묶음은 18+4×7=46ms 대 48ms입니다. “반복 계산이 빠름”만 보면 첫 호출의 비용을 놓칩니다. 이 수치는 계산용 가정이며 실제 브라우저·툴체인 성능이 아닙니다.

독립 확인

위 같은 입력·재사용 조건에서 2묶음과 5묶음의 총 시간을 각각 구하세요. 매 묶음마다 모듈을 새로 초기화한다면 결론이 같나요? 작은 add 결과가 30이라는 사실로 Wasm이 더 빠르다고 판단할 수 있나요?

풀이 확인

2묶음은 JavaScript 24ms, Wasm 18+2×7=32ms입니다. 5묶음은 JavaScript 60ms, Wasm 18+5×7=53ms입니다. 매번 초기화하면 Wasm은 묶음당 25ms여서 이 조건에서는 이득이 없습니다. 30은 값의 정확성 확인이고 수행 시간·경계 비용의 비교가 아닙니다.

Wasm의 이득은 계산 시간과 호출·로딩 비용을 함께 비교합니다

WASM FIT

Wasm의 이득은 계산 시간과 호출·로딩 비용을 함께 비교합니다

대표 입력으로 병목을 측정한 뒤 알고리즘, 실행 위치, 실행 형식을 검토합니다. Worker는 UI와 계산을 분리하고, Wasm은 계산 모듈의 실행 형식을 바꾸므로 두 선택을 함께 사용할 수도 있습니다.

개선대상인작업위치와코드형식을나눈다6노드3독립비교관계. 알고리즘은JS개선,UI스레드부담은Worker분리,코드형식은Wasm모듈검토와연결한다. 세선택은서로배타적이지않으며Worker에서JS/Wasm을함께사용가능하다. 본문18ms초기화+7ms반복모델은실측아니고mobile같다.
알고리즘·입력량CPU 병목 확인
연결 관계알고리즘·입력량 · CPU 병목 확인 → JavaScript 개선 · 같은 작업 비교
JavaScript 개선같은 작업 비교
실행 위치UI 스레드 부담
연결 관계실행 위치 · UI 스레드 부담 → Worker로 분리 · 응답성 비교
Worker로 분리응답성 비교
실행 코드 형식계산·경계 비용
연결 관계실행 코드 형식 · 계산·경계 비용 → Wasm 모듈 검토 · 초기·반복 비교
Wasm 모듈 검토초기·반복 비교

먼저 실제 병목을 측정

CPU 계산, 네트워크 대기, DOM 갱신 중 시간이 어디에 쓰이는지 확인합니다. 계산이 병목이 아니면 Wasm 도입만으로 해당 문제가 해결되기 어렵습니다.

JavaScript · 일반 웹 로직

DOM·UI·요청 처리와 일반 애플리케이션 로직에 사용합니다. 먼저 알고리즘·데이터 구조·불필요한 작업을 개선합니다.

비교: 대표 입력의 처리 시간과 사용자 반응성.

Worker · 실행 위치 분리

긴 계산이 메인 스레드를 막는다면 Worker를 검토합니다. 작업 전달·결과 수신에도 비용이 있고, 이동 자체가 계산량을 줄이지는 않습니다.

비교: UI 멈춤, 계산 완료 시간, 메시지 전달 비용.

Wasm · 계산 모듈

계산 집약적 루프나 기존 C/C++/Rust 모듈을 검토합니다. Wasm을 Worker 안에서 실행할 수도 있습니다.

비교: 계산 시간 + 로드·초기화 + JS 호출·데이터 변환.

모듈 경계를 정하기

자잘한 호출을 많이 하는 대신 큰 작업 단위로 교환할 수 있는지 확인합니다. 버퍼 소유·복사·반환 형식과 디버깅·배포 비용도 함께 평가합니다.

같은 조건으로 최종 비교

JS와 Wasm을 같은 대표 입력·기기에서 비교합니다. 처음 실행과 반복 실행을 구분하고, 실제 이득이 유지될 때 도입합니다. 로드 실패나 미지원에 대한 대체 경로도 준비합니다.


WebAssembly의 동작 원리 (간략)

WebAssembly가 웹 브라우저에서 어떻게 실행되는지 간략한 흐름을 살펴보겠습니다.

고수준 언어로 코드 작성: 개발자는 C, C++, Rust 등 원하는 언어로 고성능 로직을 작성합니다.

(예: 이미지 필터링 알고리즘)

WebAssembly로 컴파일: Emscripten (C/C++), wasm-pack (Rust)과 같은 툴체인을 사용하여 작성된 코드를 .wasm 이진 파일과 이를 로드하고 실행하기 위한 .js (Glue Code) 파일로 컴파일합니다.

브라우저 다운로드: 웹 페이지는 컴파일된 .wasm 파일과 필요한 .js 파일을 네트워크를 통해 다운로드합니다.

실제 크기는 모듈과 런타임 포함 여부에 따라 달라지지만, Wasm의 이진 형식은 전송과 파싱 효율에 유리하도록 설계되어 있습니다.

브라우저 검증 및 컴파일: 브라우저의 WebAssembly 엔진은 .wasm 이진 코드를 검증하고 컴파일합니다.

Wasm은 타입과 구조가 명확한 이진 형식이라 스트리밍, 검증, 컴파일에 유리하게 설계되어 있습니다.

실행: 컴파일된 WebAssembly 코드가 브라우저의 샌드박스 환경 내에서 실행됩니다.

JavaScript는 필요할 때 WebAssembly 모듈의 함수를 호출하고, WebAssembly는 결과를 JavaScript로 반환합니다.


WebAssembly 사용 예시

간단한 WebAssembly 모듈을 생성하고 JavaScript에서 로드하는 과정을 살펴보겠습니다.

C 언어로 간단한 합산 함수 작성 (add.c)
add.c
// add.c
int add(int a, int b) {
    return a + b;
}
Emscripten을 사용하여 WebAssembly로 컴파일

Emscripten 툴체인을 설치해야 합니다.

(설치 과정은 복잡하므로 여기서는 명령어만 제시합니다.)

# main 없이 add 함수를 내보내는 JS factory와 add.wasm 생성
emcc add.c -o add.js --no-entry -s MODULARIZE=1 -s EXPORT_ES6=1 -s EXPORTED_FUNCTIONS="['_add']"

이 명령은 add.js와 add.wasm을 생성하는 구성이며 HTML은 별도로 준비합니다. 두 파일과 index.js를 같은 경로에서 HTTP로 제공하고 module script로 로드합니다. 여기서는 툴체인 실행 결과를 관측한 것이 아니라 공식 factory API에 맞춘 예시를 제시합니다.

JavaScript에서 WebAssembly 모듈 로드 및 사용
index.js
// <script type="module" src="./index.js"></script>로 로드
import createAddModule from './add.js';

async function loadWasmModule() {
    try {
        // 생성된 JS factory가 Wasm 로드·초기화와 필요한 imports를 처리
        const module = await createAddModule();
        const addFunction = module._add; // Emscripten JS wrapper의 내보내기 이름
        const result = addFunction(10, 20);
        console.log(`WebAssembly를 사용한 덧셈 결과: ${result}`); // 성공 시 예상값: 30
    } catch (error) {
        console.error('WebAssembly 모듈 로드 또는 실행 실패:', error);
    }
}

loadWasmModule();

참고: 실제 프로덕션 환경에서는 Emscripten이 생성하는 .js (glue code) 파일을 사용하여 .wasm 모듈을 로드하고 인스턴스화하는 것이 더 편리하고 강력합니다.

이 예시는 생성된 JS wrapper의 _add를 호출합니다. raw WebAssembly.instantiate의 exports 이름과 imports 계약은 툴체인 산출물에 따라 달라지므로 이 경로와 섞지 않습니다.

Emscripten의 modularized 출력 계약은 async factory가 인스턴스 Promise를 반환하는 경로와 ES module의 default export를 설명합니다. await가 끝나기 전에 _add를 호출하는 단계로 순서를 바꾸지 않습니다. 초기화 거부는 catch로 가고, 초기화가 끝나도 기대한 _add가 함수가 아니라면 호출에서 오류가 발생합니다.

독립 확인

factory가 파일 로드 실패로 거부되는 경우에 addFunction 호출까지 도달하나요? factory가 완료되어도 _add가 누락되었다면 무엇을 점검해야 하나요? 두 파일을 단순히 다운로드한 것을 호출 성공으로 볼 수 있나요?

풀이 확인

초기화가 거부되면 await에서 catch로 이동해 덧셈 호출은 하지 않습니다. _add 누락은 실제 생성 wrapper의 내보내기 설정과 산출물의 조합을 확인할 문제입니다. 다운로드·초기화·함수 호출·결과 확인은 서로 다른 단계이며 둘째 파일을 받았다는 사실만으로 성공값 30을 관측한 것은 아닙니다.


WebAssembly의 미래와 활용 분야

WebAssembly는 웹 내부의 고성능 실행 형식에서 출발해 서버와 엣지 런타임까지 활용 범위를 넓혀 가고 있습니다.

  • 현재 활용 분야
    • 게임: 웹 기반 게임 엔진(Unity, Unreal Engine)의 웹 포팅, 고사양 게임 에뮬레이터.
    • 이미지/비디오 처리: 브라우저 내에서의 실시간 필터링, 압축, 편집. (예: Figma, Photoshop on Web)
    • CAD/3D 모델링: 웹 기반 3D 뷰어 및 디자인 도구.
    • 과학 계산/데이터 분석: 복잡한 수치 계산, 머신러닝 모델 추론.
    • P2P 통신: 웹RTC와 결합하여 고성능 데이터 처리.
  • 확장 방향

아래 제품·엔진 이름은 활용 분야를 이해하기 위한 사례입니다. 해당 제품의 모든 최신 버전이나 기본 배포 대상에 Wasm 지원이 있다는 보증이 아니며, 실제 적용은 선택한 버전의 공식 빌드·플랫폼 계약을 확인합니다.

  • WASI (WebAssembly System Interface): 웹 브라우저 외부 환경(서버, IoT 장치 등)에서도 WebAssembly를 실행할 수 있도록 하는 인터페이스입니다. 이는 WebAssembly를 웹을 넘어선 범용 런타임으로 확장합니다.
  • GC (Garbage Collection): 가비지 컬렉션 기반 언어(Java, C#, Go 등)를 WebAssembly로 옮기기 쉽게 만드는 방향입니다.
  • Multi-threading: 웹 워커와 공유 메모리 모델을 활용해 병렬 처리 성능을 높이는 방향입니다.
  • Debuggability: 개발자 도구에서의 디버깅 경험 개선.

WebAssembly는 연산량이 큰 기능을 웹에서 처리해야 할 때 검토할 수 있는 선택지입니다.

적용 전 JavaScript와의 경계 비용과 빌드 복잡도를 함께 확인해야 합니다.


WebAssembly 요약

Wasm을 적용할 때는 빠른 실행만 보지 말고 JavaScript와의 경계 비용, 메모리 전달, 빌드 복잡도, 대체 경로를 함께 검토해야 합니다.

이번 장에서는 웹 브라우저에서 저수준 바이너리 모듈을 실행하는 WebAssembly (Wasm)의 기초를 학습했습니다.

여러분은 WebAssembly가 JavaScript의 성능 한계를 보완하기 위해 설계된 컴팩트한 이진 실행 형식이자 저수준 컴파일 대상임을 이해했습니다.

그리고 JavaScript를 대체하는 기술이 아니라, 서로 역할을 나누는 보완 관계라는 점도 확인했습니다.

또한 WebAssembly가 C, C++, Rust 코드의 웹 실행을 가능하게 해 기존 고성능 라이브러리를 재활용할 수 있다는 점을 배웠습니다.

컴파일, 다운로드, 실행으로 이어지는 동작 흐름과 JavaScript에서 Wasm 모듈을 로드하는 기본 예시도 살펴봤습니다.

마지막으로 현재 활용 분야와 앞으로의 확장 방향까지 함께 정리했습니다.

WebAssembly는 연산량이 큰 기능을 웹에서 처리해야 할 때 검토할 수 있는 선택지입니다.

다음 절에서는 JAMstack의 빌드·배포·요청 경계를 살펴봅니다.