웹과 시스템의 만남, WebAssembly
2021년 10월 28일최근 웹 브라우저 환경에서 Windows 2000을 띄우는 신기한 서비스를 찾았습니다. 웹 브라우저에서 Windows 2000이 부팅되는 모습을 보고 신선한 충격을 받았습니다. 어떻게 웹 브라우저에 OS를 띄운거지...? 제가 알고있는 웹 상식으로는 도저히 구현할 수 없는 물건인데 이걸 어떻게 구현한건지 무척이나 궁금했습니다. 그렇습니다. 글 제목을 보고 눈치채셨겠지만, 오늘의 주인공 WebAssembly입니다.
WebAssembly(이하 웹어셈)는 이름만 보면 어마무시한 친구 같습니다. Web + Assembly의 합성어로 웹에서 어셈블리어를 돌린거 같은 느낌이 팍팍 듭니다. 아니 그러면 웹어셈을 쓰려면 어셈블리어를 써야하는건가? 웹어셈은 언어라긴 보단 웹 브라우저가 해석하는 웹 표준(open standard)에 가깝다고 보시면 됩니다. 물론 웹어셈 형식에 맞추어 직접 작성할 수 있지만 다른 언어를 웹어셈으로 변환하는 방식이 주로 쓰입니다. 필자는 웹어셈을 보고 한 줌의 눈물을 삼켰습니다.
웹어셈 가지고 할 수 있는 것들이 엄청 늘어나기 때문에 흥분을 감추지 못 했던 기억이 있습니다. 하지만 의문이 듭니다. 쉽게 말해 웹어셈은 다른 언어를 가지고 웹 브라우저에 쓸 수 있다는 건데 굳이 왜 쓰지? 현재 나온 웹 기술만으로도 충분히 온갖 서비스를 만들 수 있는데?
맞습니다. 현재 나온 웹 기술로 왠만한 것들을 구현할 수 있습니다. 심지어 React를 가지고 Windows XP 형태로 띄우기 까지 했으니 굳이? 웹어셈? 라는 의문이 들 수 있습니다. MDN 웹 문서를 참고하여 웹어셈의 장점은 다음과 같이 말할 수 있습니다.
- 이식성이 좋다
- 빠르다
전통적인 웹 브라우저는 html, css, javascript 이 세 언어를 해석합니다. 그러다 2017년, 웹 브라우저는 새로운 언어를 지원하기 시작하는데 바로 웹어셈입니다. 이로써 C, Rust, Go 등의 LLVM 기반 언어로 작성된 코드를 .wasm 형식으로 컴파일하여 웹 브라우저에서 실행 할 수 있게 됩니다. 당연히 웹 언어 삼총사만 해석할 수 있었던 시기보다 확장성, 이식성 측면에서 좋아졌겠죠?
웹어셈을 쓰면 성능면으로도 이점이 있습니다. 이를 알아보긴 위해선 우리는 웹 브라우저 엔진에 대해 잠깐 살펴봐야합니다. 그 중 크롬 웹 브라우저가 쓰는 V8 엔진이 JS와 웹어셈을 어떻게 처리하는지 간단하게 살펴보겠습니다.

크롬 웹 브라우저가 JS를 처리하는 순서는 다음과 같습니다.
- Javascript 작성
- Javascript 파싱 작업
- AST(Abstract Syntax Tree) 생성
- 생성된 AST를 Ignition(인터프리터)에 전달 후 ByteCode 생성
- ByteCode를 실행하면서 profiling을 통해 최적화가 될 수 있는 데이터를 수집 후 TurboFan(컴파일러)으로 전달 수행
- 5-1. 반복되는 코드는 최적화(optimize)를 통해 TurboFan 전달 및 Optimized Code 생성
- Optimize 취소 시 Deoptimize의 작업으로 ByteCode 실행
저희는 4~6번 과정에 집중하면 됩니다. 처음으로 JS 코드를 실행할 때 Ignition이라는 인터프리터로 들어가 ByteCode 생성 후, 실행하게 됩니다. 이후 반복되는 함수/로직은 profiling하여 TurboFan으로 보냅니다. 이를 Optimized Code로 생성하여 다음에 빠른 실행을 하도록 합니다. 중간에 타입 변환과 같은 최적화 취소가 발생 시 ByteCode로 돌아와 실행하는 과정을 거칩니다
다음은 웹어셈의 처리 순서 입니다.
- 웹어셈 작성
- Liftoff(컴파일러)를 통해 코드 실행
- 최적화 작업으로 TurboFan에 전달 후 Optimized Code 생성
웹어셈은 미리 컴파일된 형태이므로 파싱 과정이 필요없습니다. 여기서 하나 의문이 드는점이 Liftoff도 컴파일러이고 TurboFan도 컴파일러인데 왜 두개를 따로 두는냐 입니다. Liftoff는 컴파일러의 모든 과정을 한 번만 거치는 one-pass compiler입니다. 이는 훌륭한 속도를 보여주지만 최적화 작업이 이루어지지 않습니다. 따라서 Liftoff 컴파일 완료 후 다시 TurboFan으로 최적화 작업을 처리합니다[1].
웹어셈은 현재 웹 언어 기술의 부족한 부분을 메꿀 수 있는 매력적인 기술입니다. 웹어셈은 JS의 대체제가 아닌 JS를 보완하는 기술에 더 가깝습니다. 영상 편집, 게임과 같이 성능이 중요한 부분을 웹어셈으로 적용을 하기도 하고 앞서 소개한 Windows 2000처럼 Low level한 서비스를 제공하는데에도 큰 역할을 합니다. 기존의 웹 언어과 성격이 다른 녀석이지만 웹 서비스를 해치지 않도록 설계하면 분명 든든한 친구가 될 수 있을겁니다.
재미있는 기술을 만나서 자료조사 하다가 계속 딴 길로 새서 다시 돌아온다고 힘들었습니다. 더 많이 소개하고 싶었지만 저의 필력도 그렇고 머리도 그렇고 여기까지 맛보기로 소개하고 끝 맺겠습니다. 언젠가는 웹어셈으로 프로젝트 해보는 날이 오면 좋겠습니다.