SJ blog
frontend
S

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

WebAssemblyをゼロから理解する

WebAssembly(Wasm)がなぜ速いのか、どんな場面で使うべきか、JavaScriptとの連携方法、実際の活用事例までをわかりやすく解説します。

一言結論

WasmはDOM操作やJavaScript連携が多い処理では速度優位はなく、画像変換・暗号処理・ゲームエンジンのようなCPU集中型の計算においてのみJavaScriptを大幅に上回るパフォーマンスを発揮するため、用途を見極めた使い分けが重要だ。

WebAssembly とは

WebAssembly(略称: Wasm)は、ブラウザ上で動作する低レベルのバイナリ命令形式です。JavaScript ではない言語(C・C++・Rust・Go など)でコンパイルされた高速なコードをブラウザで実行できます。

ソースコード(Rust / C / C++ / Go)
    ↓ コンパイル
.wasm バイナリ
    ↓ ブラウザが読み込む
ほぼネイティブな速度で実行

なぜ速いのか

JavaScript は動的型付け言語であり、JIT コンパイラが型を推測しながら最適化します。一方 Wasm は:

  • 静的型付き: コンパイル時に型が確定している
  • バイナリ形式: パース・デコードが高速
  • 線形メモリ: GC なし、メモリ管理が予測可能

ただし「Wasm は常に JavaScript より速い」は誤解で、CPU 集中型の処理で有利で、DOM 操作は JavaScript の方が速いです。

何に使うのか

用途具体例
画像・動画処理ffmpeg.wasm、Squoosh
暗号処理TLS・ハッシュ計算
ゲームエンジンUnity、Godot
科学計算NumPy の Wasm 版
AI 推論TensorFlow.js(一部 Wasm バックエンド)
Figma、AutoCAD Web高負荷な描画処理

JavaScript から Wasm を呼び出す

最小限の例(Rust → Wasm)

// lib.rs
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}
# wasm-pack でビルド
wasm-pack build --target web
// JavaScript から読み込み
const { instance } = await WebAssembly.instantiateStreaming(
  fetch("/pkg/mylib_bg.wasm")
);

const result = instance.exports.add(3, 4); // 7

wasm-bindgen で複雑な型を扱う(Rust)

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}
import init, { greet } from "./pkg/mylib.js";

await init();
console.log(greet("世界")); // "Hello, 世界!"

JavaScript との連携コスト

Wasm ↔ JavaScript の関数呼び出しには「境界越えコスト」があります。文字列や複雑なオブジェクトを頻繁にやり取りすると遅くなります。

✅ Wasm に向いている: ループが多い・大量計算・メモリ直接操作
❌ Wasm に向かない: 頻繁な JS ↔ Wasm の往復・DOM 操作

WASI — サーバーサイドでの Wasm

WASI(WebAssembly System Interface)を使うと、Node.js や Cloudflare Workers で Wasm を実行できます。

// Node.js で Wasm を実行(WASI)
import { WASI } from "node:wasi";
import { readFile } from "node:fs/promises";

const wasi = new WASI({ version: "preview1" });
const wasm = await WebAssembly.compile(await readFile("./app.wasm"));
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);

まとめ

WebAssembly は「JavaScript を置き換えるもの」ではなく、JavaScript が苦手な重い計算処理を補完するものです。画像処理・暗号・ゲームエンジンなど CPU 集中型の処理で真価を発揮します。Rust + wasm-pack の組み合わせが今最も実用的なスタックです。


参考: WebAssembly 公式 / wasm-pack