WebAssembly が効く場面は、宣伝よりずっと少ない
WASM の利得は重い計算、まとまったデータ、少ない境界越えが揃ったときに出ます。O(n) の JavaScript ループを書き直しても、遅い読み込みと追いにくいスタックが残るだけです。
WebAssembly の売り文句はネイティブに近い速度です。それは正しいのですが、記述しているのは計算が終わったあとの状態で、読み込み、コンパイル、境界越え、データのコピーは省略されています。
3 つの条件が同時に要る
- 計算が重い:1 回の呼び出しの中に実際の計算量があり、四則演算数回ではない
- まとまったデータ:小さな配列を往復させず、大きな塊を一度に渡す
- 呼び出しが少ない:境界越えの回数が計算そのものより一桁少ない
3 つが揃えば WASM は 10 倍以上速くなります。1 つでも欠けると、利得は境界のコストに食われます。
本当に効く一群
C / C++ / Rust の実装が既にあり、それがホットパスにある場合です。画像や音声のコーデック、圧縮(zstd や brotli の高圧縮側)、暗号、物理や幾何の計算、そして決定的なサンドボックスが必要な場面(利用者が投げた式の評価、プラグイン機構)。共通点は、アルゴリズムが複雑で、境界がはっきりし、データが塊であることです。
向かない 3 種類
- DOM を触るもの:WASM から DOM には届かず、すべて JavaScript 経由になります。1 回の境界越えが処理そのものより高くつきます
- 小さな文字列処理:正規表現、テンプレート、整形。入出力が小さく、境界のコストが支配的になります
- 性能のためだけの JavaScript の書き直し:JIT は整数ループやプロパティアクセスを十分に処理します。書き直しで得られないことが多く、必ずスタックトレースが読みにくくなります
このサイトの結論:1 つも使わない
いちばん重い処理は数独の求解、ライフゲームの反復、ハッシュ、画像処理で、どれもミリ秒台です。WASM モジュールを足すと数 MB のダウンロード、コンパイル手順、ブラウザのコンソールでしか追えない呼び出し経路が増え、その代わりに体感できない高速化が手に入ります。
まず測る。ボトルネックが O(n) のループなら、別の言語で書いても O(log n) にはならない。

コメント
…