⚙️
WebAssembly(WASM)はどう動くのか?
C++/Rust/Zigコードをブラウザでネイティブ速度で実行
WebAssembly(WASM)はC++、Rust、Zigなどの静的型付け言語で書かれたコードをブラウザでネイティブに近い速度で実行するバイトコードフォーマットです。
構造ダイアグラム
📝
ソースコード
C / C++
Rust
Zig
Go (tinygo)
① コンパイル
→
Emscripten / wasm-pack / zig build
📦
npmパッケージ
.wasm(バイトコード)
JS/TSラッパー(glue)
TypeScript型
② バンドル
→
Vite / webpack
🌐
ブラウザ
WASM Runtime
WebAssembly.compile()
WebAssembly.instantiate()
JS ↔ WASM呼び出し
WASM配信方式:
A
別途.wasmファイル → fetch()でロード → キャッシュ可能
B
base64インライン → JSバンドルに内蔵 → 追加リクエストなし(ghostty-web方式)
ポイント
- JavaScriptはWASMにコンパイル不可 — WASMは静的型付け言語専用のコンパイルターゲット
- WASMはDOMに直接アクセス不可 — JSラッパー(glue code)がブリッジ役
- ブラウザのサンドボックス内で実行 — ネイティブアプリと同一のセキュリティ
- 実例: Figma(C++)、FFmpeg.wasm(C)、Ghostty Web(Zig)、Photoshop(C++)
動作フロー
1
ソースコード記述(C++, Rust, Zigなどの静的型付け言語)
2
言語別WASMコンパイラで.wasmバイトコード生成(Emscripten, wasm-pack, zig buildなど)
3
JS/TSラッパー(glue code)作成 — WASM関数をJS APIとして公開、Web APIブリッジ
4
npmパッケージとして配布(例: npm install ghostty-web)。WASMはbase64インラインまたは別.wasmファイルでバンドル
5
フロントエンドビルドツール(Vite, webpack)がパッケージをバンドル。dynamic import()でWASMモジュール読み込み
6
ブラウザがWebAssembly.compile() → instantiate()でバイトコードをコンパイルしインスタンス生成
7
JSからWASM関数呼び出し ↔ WASMからJSコールバック呼び出し — 双方向通信で連携
メリット
- ✓ ネイティブに近い実行速度(JS比10〜100倍高速な演算)
- ✓ C++/Rustなど既存コードベース再利用(30年前のC++コードもwebで実行)
- ✓ サンドボックス実行(ブラウザのセキュリティモデルがそのまま適用)
- ✓ 言語非依存(コンパイルさえできればどの言語でもOK)
- ✓ サーバー負荷軽減(重い演算をクライアント側で処理)
デメリット
- ✗ DOM/Web API直接アクセス不可 — 必ずJS glue code経由
- ✗ ビルド環境が複雑(Emscripten/wasm-packインストール、クロスコンパイル)
- ✗ 初期ロード時間(.wasmダウンロード + コンパイルオーバーヘッド)
- ✗ デバッグが困難(ソースマップ未成熟、console.log不可)
- ✗ メモリ管理が手動(GCなし)、JS↔WASMデータ交換にシリアライゼーションコスト
ユースケース
Figma(C++ 2Dレンダリングエンジンをwebでネイティブ速度で)
FFmpeg.wasm(サーバー不要でブラウザ上で動画変換)
Ghostty Web(Zigターミナルパーサーをwebターミナルで使用)
Google Earth Web(C++ 3D地図レンダリング)
AutoCAD Web(C++ CADエンジン30年分のコード再利用)
Photoshop Web(C++画像処理エンジン)