この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、せーのです。今日はChromeのアップデートで搭載された、これからのWebを変える(かもしれない)技術をご紹介します。「WebAssembly」、と言います。
WebAssemblyって何?
Chromeの最新バージョンは大きなアップデートとして「CSS Grid Layoutのサポート」と「Media Session Apiのサポート」があります。CSS Grid Layoutは今までHTMLのTableタグで表現していたような縦と横、2次元のレイアウトをCSSで表現できる、という機能、Media Session APIはAndroidのChromeでロック画面などに出てくる音楽、動画のコントロール機能にブラウザからアクセスできる、というものです。これは特にモバイルで動画や音楽を流すWebサイトを作っている人には嬉しい機能ではないでしょうか。他にも「chrome://plugins」が廃止される等色々なアップデートが行われています。
そんなメジャー機能に少し隠れていますがChromeの最新版ではいよいよ「WebAssembly」が正式サポートされました。ほぼ同時期にリリースされたFirefoxの最新版「Firefox 52」でも同じくサポートされています。
「WebAssembly」とはApple、Google、Mozilla、Microsoftの4社にて共同開発している「Webブラウザをプラットフォームとしたバイナリフォーマット」のことです。略称は「wasm」と言います。
今までは「Webブラウザ上で動かすアプリ」と言えばJavaScriptで実装することがほとんどでした。しかしJavaScriptはスクリプト言語のため、一処理ごとにコンパイルが走ります。どうしても速度的にはネイティブアプリにかなわない部分がありました。そこで今までFlash, Silverlight, Java Applet等色々なプラグインが開発され、ユーザーの「ヌルヌル感」をなんとか実現しようとしていました。
昨今ではプラグインに対する拒否反応と入れ違うかのように「asm.js」という低水準言語が動くJavaScriptのサブセット等も開発されており、時代は変われど人々の「ヌルヌル」に対する要求は尽きることはありませんでした。今回出てきた「WebAssembly」がその救世主になるかもしれません。
WebAssemblyではCやC++をそのままコンパイルでき、機械言語として動かすことができます。ユーザーは当然「ヌルヌル」を手にすることが出来ます。さらにプラットフォームが一般PCにはほぼ間違いなく入っている「ブラウザ」というプラットフォームになるため、OSを気にする必要はなくなります。ユーザーはブラウザがWebAssemblyに対応しているか、それだけを考えれば良いことになります。今回ChromeとFirefoxが対応しましたが、Microsoft社の「Edge」Apple社の「Safari」も計画通りに行けば2017年第1四半期には搭載されると見られています。
特徴
では軽くWebAssemblyの特徴を押さえておきましょう。
速い
まずはコレです。コンパイルされたバイトコードの状態でブラウザにロードされるため、圧倒的に速いです。
どこでも動く
プラットフォームがWebブラウザになり、また大手の各社が共同開発しているので、メジャーなブラウザではほぼWebAssemblyが動く、と考えられています。
デバッグしやすい
コンパイル言語の最大の特徴として「デバッグしにくい」という事が挙げられます。今の時代アセンブラをしこしこ読んでいるエンジニアはなかなかいないですよね。WebAssemblyではソースコードはAST(Abstruct Syntax Tree:抽象構文木)で表され、テキストとして表現できますので、コードのデバッグがアセンブラに比べて簡単です。Webassemblyはwasmというモジュールでクライアントにダウンロードされるのですが、それをブラウザ側ではHTMLソースを開くようにASTで見ることができます。
;; Iterative factorial named
(func $fac-iter (param $n i64) (result i64)
(local $i i64)
(local $res i64)
(set_local $i (get_local $n))
(set_local $res (i64.const 1))
(label $done
(loop
(if
(i64.eq (get_local $i) (i64.const 0))
(break $done)
(block
(set_local $res (i64.mul (get_local $i) (get_local $res)))
(set_local $i (i64.sub (get_local $i) (i64.const 1)))
)
)
)
)
(return (get_local $res))
)
サンプルを動かしてみた
それではとりあえずどのくらいヌルヌルするのか、やってみましょう。 まずはChromeの設定を開きます。
WebAssemblyが搭載されているChromeは57なので、バージョンが古い場合はアップデートが自動でかかります。Chromeを再起動すると最新版になります。
それではサンプルをいくつか動かしてみましょう。まずは公式にあるDEMOです。
Tank!というゲームが遊べます。a,d,s,wとSPACEボタンが1P, 矢印ボタンとEnterキーが2Pで戦車を撃ち合うゲームのようです。ヌルヌルですね!
これはUnityで作られてるんですね。
次はCやC++をasm.jsに変換する時に使うトランスコンパイラのEmscriptenが作っているDEMOです。
https://kripken.github.io/BananaBread/cube2/bb.html
Cube2というゲームです。撃ち合いのゲームのようですね。普段FPSとか全くやらない私にはちょっと怖かったです。
まとめ
いかがでしたでしょうか。やはり特徴としては画面のロード時にコードがコンパイルされてクライアントに落ちてきて(wasmファイル)実行されるバイナリフォーマットであること、それにも関わらずデバッグはテキストで見えること、でしょうか。何よりもWeb標準、プラグイン無し、というのが嬉しいです。HTML5でゴリゴリ書いてた人も恐らくこちらがベースになっていくでしょうし、ひょっとしたらiOSやAndroidのアプリ開発者もWebAssemblyに移行することでどのOSでも同一コードのアプリが動かせるようになるため(しかも審査なし)、大移動が起こるかもしれません(それにはC/C++の壁がありますが。。。)。
いずれにしてもWebassemblyが浸透するにつれてWebやモバイルの世界は大きく変わるかもしれません。