💭

WebAssemblyとJavaScript

に公開

はじめに

Rust+WASMで開発を計画している中で、まだWASM自体をいまいち理解できていない気がしたので、内容を整理しました。
私と同じようにWASMに馴染みがない方の参考になれば嬉しいです。

WebAssemblyとは?

WebAssembly(WASM)は、Webブラウザ上でアプリケーションを実行するためのバイナリフォーマット。
JavaScriptを完全に置き換えるものではなく、JavaScriptでは苦手だった重い処理を補完する存在として注目を集めているらしい。

WASMはC、C++、Rustなどのコンパイル言語をブラウザで動かせるように変換され(.wasm形式)、ネイティブ並みのパフォーマンスを提供する。

そもそもJavaScriptはなぜブラウザ上で動かせるのか?

WASMとの違いを理解するために、JavaScriptの話から書いていきます。

JavaScriptの歴史

JavaScriptはWebページにインタラクティブな要素を追加するために開発された背景があり、Web標準化団体であるECMA Internationalによって、ECMAScriptという規格で標準化され、現在に至る。
この標準化により、ブラウザベンダー間(Chrome,Firefoxなど)でJavaScriptの一貫した実装が可能となり、開発者は幅広いブラウザで動作するスクリプトを作成できるようになった。

JavaScriptエンジン

ブラウザでJavaScriptが動作するのは、各ブラウザに組み込まれているJavaScriptエンジンによるもの。
このエンジンはJavaScriptのコードを読み取り、実行可能なバイト、マシンコードに変換し、処理を行う。

実行の仕組み

  1. パース
    ブラウザがJavaScriptファイルを受け取ると、パーサーがコードをトークン(単語)に分解し、抽象構文木(AST)というツリー構造のデータに変換する。

  2. コンパイル
    ASTはJITコンパイラによって、中間コードやバイトコードにコンパイルされる。
    ※JIT(Just-In-Time)コンパイルは実行中に最適化を行い、パフォーマンスを向上する仕組み

  3. 実行
    バイトコードは仮想マシンで実行され、必要に応じてネイティブコードに変換されてCPU上で動作する。

ざっくりとした整理になりましたが、エンジン内では複雑な最適化プロセスが行われているようです。

WebAssemblyとJavaScriptの違い

  • コンパイル済みバイナリ
    WASMは事前にコンパイルされたバイナリ形式のため、ブラウザが直接実行でき、追加のコンパイルやJIT処理がほとんど不要になる。
    これにより計算量が多いタスクやパフォーマンスが求められるアプリケーションで高い効果を発揮する。

  • 低レベルアーキテクチャ
    WebAssemblyは仮想マシンが中間コードを解釈するのではなく、ほぼネイティブのCPU命令に近いコードを実行するため、ブラウザ内のパフォーマンスが向上する。

※他にもメモリ管理や型の扱いなどの違いがありますが、私が魅力に感じた部分のみ列挙しています🙇

(補足)Node.jsとの関係性

Node.js(※)もWebAssemblyをサポートしており、WebブラウザのようにWASMの実行が可能。
これにより、Node.jsでのアプリケーション開発においてもWebAssemblyを活用可能とのこと。

※JavaScriptがWebブラウザ外で動作させるためのランタイム環境(バックエンド開発で利用が多い)

まとめ

3Dを扱う物理演算やAI推論など、重めの計算が必要な場面でWASMは活躍しそうですね。
WASMは面白い技術だと思うのですが、文章だけでは理解が難しい部分もあるので実際に開発で使ってみるのが理解の近道だと思います。

RustとWebAssemblyによるゲーム開発
参考資料として最近読み終えた書籍です。
翻訳の質が高く、最初から最後まで著者の感情(※)が伝わる面白い内容でしたので、もしRustにも興味がありましたらお勧めします。
※Rustを褒めることもあれば、実装に若干文句を言ったりしています。(「JavaScriptで書いたほうが良かったような気がしてきた」など)

Discussion