WebAssemblyとは何ですか?次世代のウェブプラットフォームの説明

20年前から、Webブラウザでネイティブに使用できるプログラミング言語はJavaScriptだけでした。サードパーティのバイナリプラグインのゆっくりとした死により、JavaやFlashのActionScriptなどの他の言語がWeb開発の第一級市民として除外されました。CoffeeScriptのような他のWeb言語は、JavaScriptにコンパイルされているだけです。

しかし今、私たちは新しい可能性を持っています:WebAssembly、または略してWASM。WebAssemblyは、Webアプリケーションのネイティブに近いパフォーマンスを約束する、小さくて高速なバイナリ形式です。さらに、WebAssemblyはあらゆる言語のコンパイルターゲットになるように設計されており、JavaScriptはその1つにすぎません。すべての主要なブラウザーがWebAssemblyをサポートするようになったので、WebAssemblyとしてコンパイルできるWeb用のクライアント側アプリの作成について真剣に考え始める時が来ました。

WebAssemblyアプリはJavaScriptアプリに取っ代わるものではないことに注意してください。少なくとも、まだです。代わりに、WebAssemblyをJavaScriptのコンパニオンと考えてください。JavaScriptが柔軟で、動的に型付けされ、人間が読めるソースコードを介して配信されるのに対し、WebAssemblyは高速で、強く型付けされ、コンパクトなバイナリ形式で配信されます。

開発者は、ゲーム、音楽ストリーミング、ビデオ編集、CADアプリケーションなど、パフォーマンスを重視するユースケースについてWebAssemblyを検討する必要があります。

WebAssemblyのしくみ

W3Cによって開発されたWebAssemblyは、その作成者の言葉では「コンパイルターゲット」です。開発者はWebAssemblyを直接作成しません。選択した言語で記述し、WebAssemblyバイトコードにコンパイルします。次に、バイトコードはクライアント上で(通常はWebブラウザーで)実行され、ネイティブマシンコードに変換されて高速で実行されます。

WebAssemblyコードは、JavaScriptよりも読み込み、解析、実行が高速であることを目的としています。WebAssemblyをWebブラウザーで使用する場合でも、WASMモジュールをダウンロードしてセットアップするオーバーヘッドがありますが、他のすべての同等のWebAssemblyはより高速に実行されます。WebAssemblyは、現在JavaScriptに存在するのと同じセキュリティモデルに基づいて、サンドボックス化された実行モデルも提供します。

現在、WebブラウザでWebAssemblyを実行することが最も一般的な使用例ですが、WebAssemblyはWebベースのソリューション以上のものを目的としています。最終的に、WebAssemblyの仕様が形になり、より多くの機能が組み込まれると、モバイルアプリ、デスクトップアプリ、サーバー、その他の実行環境で役立つ可能性があります。

WebAssemblyのユースケース

WebAssemblyの最も基本的な使用例は、ブラウザー内ソフトウェアを作成するためのターゲットとしてです。WebAssemblyにコンパイルされるコンポーネントは、さまざまな言語のいずれかで記述できます。次に、最終的なWebAssemblyペイロードがJavaScriptを介してクライアントに配信されます。

WebAssemblyは、ゲーム、音楽ストリーミング、ビデオ編集、CAD、暗号化、画像認識など、パフォーマンスを重視するブラウザベースのユースケースを念頭に置いて設計されています。

より一般的には、特定のWebAssemblyのユースケースを決定する際に、次の3つの領域に焦点を当てることが有益です。

  • ターゲット可能な言語ですでに存在する高性能コード。たとえば、すでにCで記述された高速数学関数があり、それをWebアプリケーションに組み込みたい場合は、それをWebAssemblyモジュールとしてデプロイできます。アプリのパフォーマンスがそれほど重要ではない、ユーザー向けの部分はJavaScriptのままにすることができます。
  • JavaScriptが理想的ではない、最初から作成する必要がある高性能コード。以前は、asm.jsを使用してそのようなコードを記述していた可能性があります。それでもそうすることはできますが、WebAssemblyはより優れた長期的なソリューションとして位置付けられています。
  • デスクトップアプリケーションをWeb環境に移植する。asm.jsとWebAssemblyのテクノロジーデモの多くは、このカテゴリに分類されます。WebAssemblyは、HTMLを介して提示される単なるGUIよりも野心的なアプリの基盤を提供できます。(WebDSP、Zen Garden、およびTanksのデモを参照してください。)ただし、デスクトップアプリケーションがユーザーとインターフェイスするすべての方法をWebAssembly / HTML / JavaScriptの同等のものにマップする必要があるため、これは簡単な演習ではありません。

パフォーマンスの限界を押し上げていない既存のJavaScriptアプリがある場合は、WebAssemblyの開発のこの段階でそのままにしておくのが最善です。ただし、そのアプリを高速化する必要がある場合は、WebAssemblyが役立つ場合があります。

WebAssembly言語のサポート 

WebAssemblyは直接作成するためのものではありません。名前が示すように、これは、高レベルで人間に優しいプログラミング言語というよりも、マシンが消費するアセンブリ言語のようなものです。WebAssemblyは、CやJavaのようなものよりも、LLVM言語コンパイラインフラストラクチャによって生成される中間表現(IR)に近いものです。

したがって、WebAssemblyを操作するためのほとんどのシナリオでは、高級言語でコードを記述し、それをWebAssemblyに変換します。これは、次の3つの基本的な方法のいずれかで実行できます。

  • 直接コンパイル。ソースは、言語独自のコンパイラツールチェーンを介してWebAssemblyに翻訳されます。Rust、C / C ++、Kotlin / Native、およびDはすべて、これらの言語をサポートするコンパイラーからWASMを発行するネイティブな方法を備えています。
  • サードパーティのツール。この言語のツールチェーンにはネイティブのWASMサポートがありませんが、サードパーティのユーティリティを使用してWASMに変換できます。Java、Lua、および.Net言語ファミリーはすべて、このようなサポートを提供しています。
  • WebAssemblyベースのインタープリター。ここでは、言語自体はWebAssemblyに翻訳されていません。むしろ、WebAssemblyで記述された言語のインタープリターは、その言語で記述されたコードを実行します。インタプリタは数メガバイトのコードである可能性があるため、これは最も面倒なアプローチですが、言語で記述された既存のコードをほとんど変更せずに実行できます。PythonとRubyはどちらも、WASMに翻訳されたインタープリターを持っています。

WebAssemblyの機能

WebAssemblyはまだ初期段階です。WebAssemblyのツールチェーンと実装は、本番テクノロジよりも概念実証に近いままです。とはいえ、WebAssemblyのカストディアンは、一連のイニシアチブを通じてWebAssemblyをより便利にすることを目指しています。

ガベージコレクションプリミティブ

WebAssemblyは、ガベージコレクションされたメモリモデルを使用する言語を直接サポートしていません。LuaやPythonなどの言語は、機能セットを制限するか、ランタイム全体をWebAssembly実行可能ファイルとして埋め込むことによってのみサポートできます。ただし、言語や実装に関係なく、ガベージコレクションされたメモリモデルをサポートするための作業が進行中です。

スレッド化

スレッドのネイティブサポートは、RustやC ++などの言語に共通です。WebAssemblyにスレッドのサポートがないということは、WebAssemblyを対象とするソフトウェアのクラス全体をこれらの言語で記述できないことを意味します。WebAssemblyにスレッドを追加するという提案では、そのインスピレーションの1つとしてC ++スレッドモデルを使用しています。

バルクメモリ操作とSIMD

バルクメモリ操作とSIMD(単一命令、複数データ)並列処理は、データの山を粉砕し、機械学習や科学アプリのように、チョークを防ぐためにネイティブCPUアクセラレーションを必要とするアプリケーションに必須です。新しいオペレーターを介してこれらの機能をWebAssemblyに追加する提案が出されています。

高水準言語構造

WebAssemblyで検討されている他の多くの機能は、他の言語の高レベルの構造に直接マップされます。

  • 例外はWebAssemblyでエミュレートできますが、WebAssemblyの命令セットを介してネイティブに実装することはできません。提案されている例外計画には、C ++例外モデルと互換性のある例外プリミティブが含まれており、WebAssemblyにコンパイルされた他の言語で使用できます。
  • 参照型 を使用すると、ホスト環境への参照として使用されるオブジェクトを簡単に渡すことができます。これにより、ガベージコレクションやその他の多くの高レベル関数をWebAssemblyに実装しやすくなります。
  • 末尾呼び出し、多くの言語で使用されるデザインパターン。
  • PythonまたはC#のタプルを介して、複数の値を返す関数
  • 符号拡張演算子、便利な低レベルの数学演算。(LLVMはこれらもサポートしています。)

デバッグおよびプロファイリングツール

トランスパイルされたJavaScriptの最大の問題の1つは、トランスパイルされたコードとソースを相互に関連付けることができないため、デバッグとプロファイリングが難しいことでした。WebAssemblyでも同様の問題があり、同様の方法で対処されています(ソースマップのサポート)。計画されたツーリングサポートに関するプロジェクトのメモを参照してください。