What Is WebAssembly?
WebAssembly (Wasm) is a portable, compact, fast-loading binary format for the web. C, C++, Rust, Go, Java, C#, and other toolchains can compile to Wasm and ship it to the browser to complement JavaScript. Real-world uses include large games, Google Earth, Magnum, Blazor, and AutoCAD on the web — this post focuses on our AutoCAD case.
Why WebAssembly?
Mainly performance. JavaScript struggles with heavy CPU/memory work, drawing, and high concurrency. The platform has added pieces like SharedArrayBuffer, but limits remain. We used Emscripten and asm.js, later Binaryen, for roughly 12–15% overall speedup.
How We Use It
We compile C++ to Wasm with Emscripten. Main challenges:
- Huge codebase
- Long startup
- Desktop vs web differences
Sync vs async I/O
The main thread cannot block without jank; rewriting is costly and third-party libs may need changes. Web Workers help but blocking calls, message timing, no shared memory, and no semaphore-like sync make communication hard.
Approaches we considered
Emterpreter — bytecode + interpreter for sync-like behavior via saved stack/state and timers. Too slow; hard to identify stack functions; hard to maintain.
SharedArrayBuffer — fast but manual serialization; Spectre concerns led browsers to disable it in many cases.

Service Worker + sync XHR — simulate blocking with sync XHR; intercept network in a service worker. New SW versions require refresh; version consistency needs background updates; startup waits for SW ready.

Memory access consistency
First: asm.js/Wasm was slow on forced casts (e.g. char* → int*). We standardized on memcpy:
| |
Second: Emscripten function pointers require strict types:
| |
After optimization, 82 subprojects improved ~50%; builds dropped from ~90 minutes to ~50.
Exceptions
Some exceptions were removed for efficiency.
Summary
Startup flow: UI thread → UI init → service worker init → web worker init (Wasm init, fonts, i18n, etc.) → C++ startup.
Optimization: Wasm instantiation dominates worker startup — faster instantiation and compiler flags (-O3, smaller code, fewer exceptions) help.