近年、Webアプリケーションの機能と複雑さは急速に増大しています。ブラウザ上で動作する3Dゲーム、リアルタイムの画像処理、機械学習の実行など、かつてはデスクトップアプリケーションでしか実現できなかった機能が、今ではWeb上で当たり前のように実現されています。

しかし、これらの高度な機能を実現するには、従来のJavaScriptだけでは性能面での制約が大きな課題となっていました。特に計算処理が重いアプリケーションでは、処理速度の遅さがユーザー体験を大きく損なう原因となっていたのです。

この課題を解決するために登場したのが、WebAssembly(略称:Wasm)です。本記事では、WebAssemblyの基礎から実践的な活用方法まで、詳しく解説していきます。

プログラミング言語の世界を理解する

高級言語と低級言語の違い

WebAssemblyの仕組みを理解するためには、まずプログラミング言語の基本的な区分について知っておく必要があります。プログラミング言語は、人間とコンピュータの間の「翻訳」という観点から、大きく2つのカテゴリーに分類されます。これは、私たちが普段使用している言語(自然言語)とコンピュータが理解する言語(機械語)の間には大きな隔たりがあるためです。

高級言語(人間向けの言語)

私たちがよく目にするプログラミング言語のほとんどは高級言語に分類されます。これらの言語は、人間が理解しやすいように設計されており、英語に近い文法と構造を持っています。実際の開発現場でも、その分かりやすさと生産性の高さから、高級言語が広く採用されています。

  • :JavaScript、TypeScript、Python、Javaなど

  • 特徴
    • 人間が理解しやすい文法
    • 英語に近い命令文が使用可能
    • 開発効率が高い
  • サンプルコード
    let total = price + tax;
    if (total > 1000) {
      applyDiscount();
    }
    

低級言語(コンピュータ向けの言語)

一方、低級言語はコンピュータにより近い層で動作する言語です。高級言語と比べると人間には読みづらいものの、コンピュータが直接理解できる形式に近いため、実行速度が格段に速いという大きな利点があります。ハードウェアの制御や高性能が求められる処理では、この低級言語が重要な役割を果たします。

  • :アセンブリ言語、機械語
  • 特徴
    • コンピュータが直接理解できる形式
    • 人間には読みにくい
    • 実行速度が速い
  • サンプルコード
    MOV EAX, [price]
    ADD EAX, [tax]
    CMP EAX, 1000
    JG discount
    

プログラムの実行の仕組み

では、私たちが書いた高級言語のコードは、どのようにしてコンピュータで実行されているのでしょうか。実は、全てのプログラムは最終的に低級言語に変換されて実行されています。その過程を具体的に見ていきましょう。

  1. プログラム作成:プログラマーが高級言語でコードを書く
  2. 変換:コンパイラやインタプリタが低級言語に変換
  3. 実行:コンピュータが低級言語を実行

WebAssemblyとは

ここまでプログラミング言語の基本的な分類について見てきましたが、それではWebAssemblyとは具体的にどのような技術なのでしょうか。WebAssemblyは、ブラウザ上で動作する新しい形式の低級言語として設計されました。この革新的な技術は、Webアプリケーションに新たな可能性をもたらしています。

WebAssemblyの特徴

WebAssemblyが注目を集める理由は、従来のWeb技術では実現が難しかった特長を備えているからです。その主な特徴を見ていきましょう。

高速性
WebAssemblyの最大の特徴は、その処理速度にあります。従来のJavaScriptと比較して、以下のような利点があります。

  • JavaScriptより数倍速く実行可能
  • コンピュータが直接理解できる形式で動作

多言語対応

WebAssemblyのもう一つの大きな特徴は、様々なプログラミング言語からWebAssemblyにコンパイルできることです。これにより、各言語の特長を活かしたWeb開発が可能になります。

  • 様々なプログラミング言語をWebAssemblyに変換可能
  • 対応言語
    • C/C++
    • Rust
    • Go
    • Kotlin/Native
    • AssemblyScript

クロスブラウザ対応
WebAssemblyは、主要なブラウザベンダーが共同で策定した標準技術です。

  • 主要ブラウザ(Chrome、Firefox、Safari、Edge)で動作

WebAssemblyの形式

WebAssemblyのコードは、開発時と実行時で異なる2つの形式で扱われます。

  • テキスト形式.wat):人間が読める形式。開発やデバッグに使用
  • バイナリ形式.wasm):コンピュータが実行する形式。配布時に使用

JavaScriptとの関係

WebAssemblyは、既存のJavaScript環境を置き換えるものではありません。むしろ、JavaScriptを補完し、より豊かなWebアプリケーションを実現するための技術として位置づけられています。

役割分担

効果的なWebアプリケーション開発のために、WebAssemblyとJavaScriptはそれぞれの得意分野で使い分けることが重要です。

WebAssemblyが得意なこと

高速な実行が必要な処理を担当します。

  • 複雑な数値計算
  • 画像・音声処理
  • 物理演算
  • 暗号化処理

JavaScriptに任せること

ユーザーインターフェースやブラウザとの連携に関する処理を担当します。

  • ウェブページの操作(DOM操作)
  • ネットワーク通信
  • ユーザーインターフェース制御

主な使用用途とユースケース

WebAssemblyは、すでに多くの実用的なアプリケーションで活用されています。具体的な例を見ることで、その可能性をより深く理解できるでしょう。

TensorFlow.js

機械学習ライブラリのTensorFlow.jsでは、WebAssemblyバックエンドを提供しています。ドキュメント中では、以下のように説明されています。

小さなモデルでは、WebGL シェーダーを実行するオーバーヘッドコストが固定されているため WASM は WebGL よりもパフォーマンスが優れています

TensorFlow.js | JavaScript デベロッパー向けの機械学習

Babylon.js

Babylon.js 6は、2D/3Dモデルを描画するライブラリです。バージョン6では、物理演算ライブラリにWebAssemblyを採用し、高速な描画を実現しています。

Babylon.js: Powerful, Beautiful, Simple, Open - Web-Based 3D At Its Best

Unity

3Dゲームエンジンとして有名なUnityでは、WebGLビルドでWebAssemblyを利用しています。これにより、Unityゲームをブラウザ上でも遊べるようになっており、かつ高速な描画を実現しています。

Unity のリアルタイム開発プラットフォーム | 2D/3D、VR/AR エンジン

Photoshop Web

Photoshop Webは有名な画像編集ソフトウェアであるPhotoshopのブラウザ版です。WebAssemblyのマルチスレッド処理、例外処理などを活用して、高速な画像処理を実現しています。

Adobe Photoshop

WebAssemblyの開発環境のセットアップ

WebAssemblyを開発する方法は幾つかあります。本筋とも言えるのはRustを使う方法だと思います。しかし、JavaScriptとは異なるプログラミング言語なので、学習コストがかかってしまいます。そこで、本記事ではAssemblyScriptを使ってWebAssemblyを開発する方法を紹介します。

AssemblyScriptについて

AssemblyScriptは、TypeScriptのサブセット言語になります。サブセットなので、TypeScriptの一部の機能を利用できる言語になります。AssemblyScriptは、TypeScriptのコードをWebAssemblyに変換するツールチェーンを提供しています。そのため、TypeScriptの知識があれば、WebAssemblyを手軽に開発できます。

セットアップ

開発はNode.jsで行います。Node.jsをインストールした上で、任意のディレクトリを作成します。

$ mkdir wasm-sample
$ cd wasm-sample

そして、AssemblyScriptをインストールします。

$ npm init -y
$ npm install --save-dev assemblyscript

インストールしたら、WebAssemblyのプロジェクトを初期化します。

$ npx asinit .

初期化が終わると、以下のように多数のフォルダとファイルが生成されます。

主なフォルダとファイルの説明は以下の通りです。

./assembly/
  ├── index.ts          # メインのソースコード
  ├── tsconfig.json     # TypeScript設定
  └── tests.ts          # テストコード

./build/
  ├── debug/            # デバッグビルド成果物
  ├── release/          # リリースビルド成果物
  └── .gitignore       # Git設定

./tests/
  └── index.js         # テストランナー

asconfig.json           # AssemblyScript設定
index.html             # 動作確認用HTML
package.json           # プロジェクト設定

デフォルトの assembly/index.ts は以下のようになっています。引数を受け取り、それを足して返す関数です。

// The entry file of your WebAssembly module.

export function add(a: i32, b: i32): i32 {
  return a + b;
}

利用する index.html は以下のようになっています。公開されている aaa 関数を実行しています。

<!DOCTYPE html>
  <html lang="en">
  <head>
    <script type="module">
      import { add } from "./build/release.js";
      document.body.innerText = add(1, 2);
    </script>
  </head>
  <body></body>
</html>

ビルド

AssemblyScriptのコードをWebAssemblyにコンパイルするには、以下のコマンドを実行します。

$ npm run asbuild

実行

ビルドが成功すると、build/release.wasm が生成されます。このファイルをブラウザで実行することで、WebAssemblyが動作します。実行はブラウザ経由で、 HTTP/HTTPS経由で行わないといけなません。以下のようにサーバーを立ち上げて http://localhost:3000/ にアクセスします。

$ npm start

以下の画像のように 3 が表示されれば成功です。

後は公式サイトのドキュメントを読んで、WebAssemblyを使った開発を進めていきましょう。

Introduction | The AssemblyScript Book

WebAssemblyで広がるWebの可能性

WebAssemblyによって、Webアプリケーションの可能性は飛躍的に広がっています。高速な実行エンジンを抜きにして、ブラウザ上で機械学習を行うのは難しいでしょう。同様に3Dゲームや画像処理も、JavaScriptだけでは実行が難しいはずです。

さらにWasmerなどのWebAssemblyランタイムが登場し、WebAssemblyをサーバーサイドで利用できるようになりました。これにより、WebAssemblyで開発したコードをサーバーサイドで実行することが可能になり、高速な処理を実現できます。

WebAssemblyの開発言語の一つであるRustは、C/C++の代替言語として注目されています。すでにLinuxカーネルの記述言語としてRustが導入されています。Rustを覚えることで、WebAssemblyだけでなく、システムプログラミングや組み込み開発にも活用できるでしょう。もちろんAssemblyScriptのように、手軽にWebAssemblyを開発する方法もあります。

まとめ

今回はWebAssemblyの基礎を紹介しました。ネットワークやDOM操作ができないといった制約はありますが、高速な計算処理は、高度化するWebアプリケーションには欠かせなくなっています。WebAssemblyは、そのような高度な処理をブラウザ上で実行するための技術です。WebAssemblyを効果的に利用して、高度なWebアプリケーションを開発していきましょう。