iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

WebAssemblyっていつ使うんですか?

はじめに

こんにちは!株式会社iimonでエンジニアをしている遠藤です。

WebAssembly(以下Wasm)は「RustやC++で書いたコードをコンパイルしてブラウザで実行できるらしい」程度のことは知っていました。ただ業務で使ったことがなく、JavaScriptやサーバーサイドとの使い分けはあまりイメージできていませんでした。

ちょうど社内勉強会の担当が回ってきたので、これを機に、「Wasmはどんな場面で選択肢になる技術なのか」を調べて整理してみます。

なお、本記事では導入手順や書き方には踏み込みません。
また、扱うのはブラウザ上での利用に絞ります(Wasmはブラウザ以外でも動きますが、そちらは対象外です)。


Wasmとは?

公式サイトでは「スタックベースの仮想マシン向けのバイナリ命令形式」として定義されています。ポイントは他の言語からコンパイルして生成されるものという位置づけで、MDNも「主に手作業で記述することを意図したものではなく、C、C++、Rust などのソース言語の効果的なコンパイルターゲットとして設計されています」と説明しています。

生成されたバイナリは、ブラウザのJavaScriptエンジン(V8、SpiderMonkey、JavaScriptCore)が読み込んで機械語にコンパイルし、CPUが実行します。ビルド時に済んでいるのは「Wasmバイナリを作るところまで」で、機械語化と実行はユーザーのブラウザ上で起きます。

なぜ作られたのか

MDNには背景も書かれています。
ウェブのVMはかつてJavaScriptしか読み込めず、それでほとんどの問題は解けていた。ただし3Dゲーム、VR/AR、コンピュータービジョン、画像・動画編集のようにネイティブ相当の性能を求める用途ではパフォーマンスの壁にぶつかる。加えて巨大なJSアプリはダウンロードとパース・コンパイルのコスト自体が重い。
こうしてブラウザの仮想マシンは、JavaScriptとWasmの2種類を読み込んで実行するようになりました。

MDNは同時に、WasmはJavaScriptを置き換えるものではなく、足りないところを補って併用するものだと明記しています。


Wasmで何ができるのか

Wasmでやれることは、大きく言えば「C、C++、Rustのような言語で書いたコードを、ブラウザで動かす」の一点です。画像処理でも、ゲームエンジンでも、CADでも、コンパイルさえ通れば載ります。ここは調べる前の認識どおりでした。

引っかかったのは、対応言語の一覧にPythonやRubyが並んでいるのを見たときです。インタプリタ言語をWasmに載せるって、どういうことなんだろう。 Pythonはコンパイルして配布する言語ではないし、Wasmのほうは「コンパイル先」のはずで、どうにも噛み合いません。

答えは単純でした。
CPythonもCRubyもC言語で書かれています。 Cで書かれたコードは前からWasmにできるので、Pythonの処理系のほうを載せてしまえば、その上でPythonが動く。それだけの話でした。

  • Pyodide … CPythonをEmscriptenでWasmにコンパイルしたもの。NumPy、pandas、SciPy、Matplotlib、scikit-learnといった、C拡張を持つライブラリまで動きます。2018年にMozillaが作りました
  • ruby.wasm … CRubyのWasm移植。Ruby 3.2(2022年12月)で公式にWASI対応が入りました

Pythonを動かすときは、CPythonという処理系が.pyを読んで実行しています。手元のマシンでも、Dockerイメージの中でも、サーバー上でも同じです。ブラウザでもその構造は変わらず、CPythonの置き場所がWasmになっただけでした。書いたPythonのコードがWasmに変換されるわけではありません。

そう分かってしまえば「インタプリタ言語をWasmに載せる」という言い方自体が、噛み合っていなかったわけです。載っているのは言語ではなく、その言語を動かすプログラムでした。

なお、2025年12月に標準化されたWasm 3.0ではガベージコレクションなどが仕様に入り、JavaやKotlin、Dartのような言語は処理系を丸ごと載せなくても直接コンパイルできるようになっています。

できないこと

2026年現在、WasmからDOMやWeb APIを直接呼ぶことはできません。画面を書き換えたい、通信したいときは、JavaScript側の関数をimportして経由します。ファイルシステムへの直接アクセスも同様です。

データの受け渡しも、数値以外はそのまま渡せません。文字列などはJS側のヒープとWasmの線形メモリの間でエンコード・デコードしてコピーすることになります。


なぜブラウザに持ち込むのか

Wasmの分かりやすい使い方は、JSアプリの中で重い処理をRustやCに置き換えて速くする、というものです。画像処理のように操作へ即座に反応させたい場面では、サーバーに投げて返ってくるまでの往復が体験を壊すので、手元で終わらせたい。ネイティブほどではないにせよ、計算主体の処理であればJavaScriptより速くなることが多いので、これは筋が通っています。

ですが、ただ高速化のためだけに、RustやCではなく処理系ごと持ち込むPythonやRubyを選ぶことは、あまりないように思えます。Wasmの上でさらに処理系を走らせるオーバーヘッドを挟む以上、JSを速くする手段として選ぶには不自然だからです。

調べていくと、価値は「Pythonのコードを、サーバーなしで実行できるようにすること」そのものにありそうでした。JSの処理を速くするためではなく、サーバーがないこと自体が目的になっている。

分かりやすい例がJupyterLiteです。Pyodideをカーネルに使ったJupyterで、静的ファイルの配信だけで動きます。 ビルドした成果物をS3やGitHub Pagesのような静的ホスティングに置けばよく、アプリケーションサーバーもコンテナも要りません。

そう考えると、効いてくるのは学習用途やデモのような場面です。サーバーを持たずにPython( NumPyもpandasも既存のコードも)が動くため、用意する側がサーバーを立てなくて済むというのがメリットかなと思いました。


実際にはどう使われているのか

実態はWeb Almanacが実クロールで解析しています。

採用率は0.35%(デスクトップ)。2021年の0.06%から大きく伸びましたが、直近2年は横ばいです。Mozillaのエンジニアも2026年2月の記事で、開発体験の悪さゆえに開発者は本当に必要なときしかWasmを使わず、結果として利用者は投資を正当化できる大企業に偏っている、と書いています。まだ広く使われる段階ではなさそうです。

モジュールサイズは両極端でした。下位50%は2KB〜14KBと非常に小さく、90パーセンタイルでは381KBまで跳ね上がる。検出された最大のモジュールは234MBだったそうです。章の結論も、Wasmは「特定のユーティリティ関数」と「フル機能のスタンドアロンアプリ」という2つの目的で使われている、とまとめています。


Wasmが候補に入るのはどんなときか

ここまでを踏まえると、こう整理できました。

JavaScriptでは足りない

Wasmが作られた理由そのものです。ただ「重い処理でUIが固まる」だけなら、Web Workerで切り離すだけで済む場合もあります。性能問題の原因がバンドルサイズなのか、通信なのか、再レンダリングなのか、計算そのものなのか。まず遅さの出どころを確かめるのが先です。

既存の資産を持ち込みたい

C/C++で書かれた実装をそのまま載せることも、処理系ごと持ち込んで言語の生態系ごと使うこともできます。公式のユースケース一覧でも「すでにWebへクロスコンパイルされている言語やツールキットのより良い実行」が筆頭に挙がっていました。

ブラウザ上で処理を完結させたい理由がある

サーバーを持ちたくない、データを外に出したくない、オフラインで動かしたい、即座に反応してほしい。逆に、そうした理由が特にないなら、サーバー側に置くほうが素直だと思います。


まとめ

整理すると、Wasmはブラウザになかった実行環境を持ち込むための手段で、速さはその一側面であるという理解になりました。

パフォーマンスに関しては場面に応じて変わるので、効くかどうかは結局測らないと分かりませんが、どういうときに候補として思い出せばいいのかは分かったので、次に技術選定で迷ったときには視野が広がっていそうです。

正直、軽い気持ちで調べ始めたのですが、思っていたより奥が深く、探索しきれなかった部分がかなり残りました。
理解が至っていない箇所もあると思います。
記事の内容に誤りがありましたら、ご指摘いただけますと幸いです。

最後まで読んでくださりありがとうございます!

弊社ではエンジニアを募集しております。 ご興味がありましたらカジュアル面談も可能ですので、下記リンクより是非ご応募ください! iimon採用サイト / Wantedly


参考