WebAssemblyとは?
WebAssembly(略称:Wasm)は、ブラウザ等の環境で実行できる コンパクトなバイナリ形式(+テキスト表現)です。 JavaScriptと連携しつつ、計算負荷の高い処理をネイティブに近い性能で動かす目的で使われます。
ポイント
- 速い:バイナリで配布し、実行が効率的
- 安全:サンドボックスで実行(基本は外に勝手に出られない)
- 移植性:同じWasmを複数環境(ブラウザ/サーバー)で
誤解されがち
- Wasmは「JavaScriptを置き換える言語」ではなく、補完する実行形式
- DOM操作は基本JS側(Wasmは計算や内部処理が得意)
- 万能最適解ではなく、境界コスト(JS↔Wasm)がある
WebAssemblyで何ができますか?
重い計算
画像処理、音声処理、物理計算、暗号、圧縮、機械学習の推論など。
既存資産の移植
C/C++/Rust等のライブラリをWebへ。例えばエンコーダ/デコーダ類。
サーバー/エッジ
WASI + Wasm runtime(例:Wasmtime)で「小さく安全に」実行。
向いている/向いていない
向いている
- CPUを使う処理がボトルネック
- 既存ネイティブ資産をWebへ持っていきたい
- 安全なプラグイン実行(サンドボックス)が欲しい
向いていない
- DOMを頻繁に触るUI中心(JS/TSの方が素直)
- JS↔Wasmを超える呼び出しが大量に発生する設計
- 小さい処理を無理にWasm化(境界コストで損しがち)
用語整理(Wasm / WAT / WASI)
.wasm
実行されるバイナリ形式。配布に向いていて軽い。
.wat
人間が読めるテキスト表現(デバッグ/学習で便利)。
WASI
WebAssembly System Interface。 ファイル/時刻/乱数/標準入出力など「OSっぽい機能」を、 安全に提供するための標準化API群。 ブラウザ以外(サーバー/エッジ/組み込み)でWasmを動かすときの鍵。
JavaScriptとの連携
Web上のWasmは、基本的に JavaScriptから読み込み、関数を呼び出す形になります。 「UIやDOMはJS」「計算コアはWasm」という分担が定番です。
// example.js
// const bytes = await fetch("module.wasm").then(r => r.arrayBuffer());
// const { instance } = await WebAssembly.instantiate(bytes, importObject);
// console.log(instance.exports.add(1, 2));
※ 実運用では instantiateStreaming() や bundler/wasm-pack 等で扱うことが多いです。
データ受け渡しのコツ
- 数値計算は得意(int/float)
- 文字列や配列は「メモリ共有(Linear Memory)」経由になりがち → 設計が重要
- JS↔Wasmの呼び出し回数が多いと遅くなることがある → まとめて処理が鉄則
WasmとJavaの違い
| 観点 | Wasm | Java |
|---|---|---|
| 正体 | 低レベルのバイナリ実行形式(仮想マシン向けISA) | 言語+JVMで動くバイトコード |
| 主戦場 | ブラウザ / サーバー / エッジ(WASIなど) | サーバー / Android / 業務システム中心 |
| メモリ | 基本は線形メモリ(言語側のランタイムで管理) | GC中心(JVMのヒープ管理) |
| 目的 | 多言語のコンパイル先として移植性+安全な実行 | Java言語の実行と巨大なエコシステム |
| UI | ブラウザではDOMはJS側が基本 | GUIは別技術(JavaFX等)/ Webなら別スタック |
作り方(ツールチェーン)
代表的なルートだけ、実務でよく使う順に並べます。
Rust → Wasm(定番)
- wasm-pack / wasm-bindgen でJS連携がやりやすい
- ビルド成果物をbundlerに載せやすい
C/C++ → Wasm(資産移植)
- Emscripten が定番(既存C/C++をWebへ)
- 大きいライブラリ移植向き
// lib.rs(イメージ)
// #[wasm_bindgen]
// pub fn add(a: i32, b: i32) -> i32 { a + b }
代表ユースケース
画像/動画
フィルタ、エンコード/デコード、編集、背景処理など。
ゲーム/シミュ
物理演算、経路探索、AI推論などの重処理を担当。
プラグイン実行
Wasmを「安全な拡張機構」としてホストアプリに埋め込む。
サーバー側(WASI + ランタイム)
ブラウザ以外でも、Wasmランタイム(例:Wasmtime)上で動かし、 必要な権限(ファイル/環境変数など)だけを渡す設計ができます。
できないこと / 注意点
- DOM直操作が苦手:UIはJS/TS側が基本
- 境界コスト:JS↔Wasmの呼び出し・データ変換はタダではない
- デバッグ:慣れるまではJS単体より手間が増える
- セキュリティ:サンドボックスでも「ホストが許可した機能」は使える → 権限設計が肝
FAQ
置き換えるというより、得意分野を補完します。 UI/DOM/イベントはJSが強く、計算コアや既存ネイティブ資産はWasmが強い、という分担が一般的です。
WebAssembly の公式略称 Wasm の読み方(ワズム)です。
動きます。WASI と Wasm ランタイム(例:Wasmtimeなど)を使うと、 ブラウザ外でも安全に実行できます(権限を絞れるのが強み)。