Smart Communication Design Company
ホーム > ナレッジ > Blog > フロントエンドBlog > 2017年11月 > パフォーマンス向上の次の一手はWebAssembly

フロントエンドBlog

Webのフロントエンドを構成する技術、特にHTMLやCSS、JavaScript、またそれらに関連する話題を扱うBlogです。

パフォーマンス向上の次の一手はWebAssembly

UI開発者 加藤

Webサイトのパフォーマンスを改善する代表的な手法として「ファイルサイズを減らし、ロード時間を改善すること」、「コードを最適化し、処理速度を改善すること」の二つがあげられます。WebAssemblyを利用すれば、一度に両方の改善を行うことができます。

WebAssemblyとは

WebAssemblyとはWebブラウザ上で実行できるバイナリ形式です。これまでブラウザで実行できる言語はJavaScriptのみでしたが、EdgeがデフォルトでWebAssemblyを有効化したことで、今ではIEを除く主要なブラウザでWebAssemblyを実行することができるようになりました。 JavaScriptはテキストであるため、バイナリに比べてファイルサイズが大きかったり、実行時にパースする必要があったりなど、パフォーマンスの面で様々な課題を抱えていました。WebAssemblyを組み合わせて使うことでJavaScriptが抱えている課題の一部を改善することができます。

「C言語をこれから学ぶのはちょっと・・」と思う方も多いかもしれませんが、AssemblyScriptを利用すればTypeScriptベースで書くことができ、WebAssemblyにコンパイルすることができます。

WebAssemblyが得意とするところは物理演算のような複雑な計算です。たとえばトリボナッチ数を求める数式を計算する式をAssemblyScriptで書くと下記のようになります。

export function Tribonacci (max:i32):f64 {
    let a:i64 = 0, b:i64 = 0, c:i64 = 1, temp:i64;
    while(max > 1) {
        temp = c;
        c = a + b + c;
        a = b;
        b = temp;
        max--;
    }
    return c as f64;
}

JavaScriptに型の記述を追加しただけですが、これでWebAssemblyにコンパイルすることができます。あとはJavaScript側で変換後のファイルを読み込んでインスタンス化すれば定義した関数を実行することができるようになります。

fetch('./tribonacci.wasm').then(response =>
    response.arrayBuffer()
).then(bytes =>
    WebAssembly.compile(bytes)
).then(module =>
    WebAssembly.instantiate(module)
).then(instance => {
    instance.exports.Tribonacci(50);
});

JavaScriptと比較してみた結果、7割程度の時間で計算することができました。またこの差は実行回数を増やせば増やすほど広がっていきます。

現状はまだJavaScript側で.wasmファイルを読み込むという処理が必要ですが、MDNのWebAssemblyのコンセプトページには、今後<script type='module' src='./tribonacci.wasm'>のように読み込むことが可能になることが記載されています。中身が不明確なファイルを使うときは注意が必要ですが、WebAssemblyを使用するためのハードルがどんどん下がっているように感じます。

WebAssemblyの使いどころ

ではどんなサイトでもWebAssemblyを使うべきかといえばそうではありません。たとえば、下記のような簡単な計算をWebAssemblyを使って実行してみると、

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

単純にJavaScriptで計算したほうが早くなってしまいました。WebAssemblyは主にはゲームなどの高いパフォーマンスが求められるコンテンツや、3Dモデルの情報をパースしたり物理演算のような複雑な処理や計算が必要なコンテンツで真価を発揮することができるようです。

まとめ

私はこれまで「WebAssemblyはCやC++を書いている人のためのもの」という印象が強く、あまり情報をキャッチしてこなかったのですが、今後さらにパフォーマンスを向上させる上では避けて通れない道だと認識しました。カンファレンスのトピックスとして取り上げられるなど、近年Web業界ではサイトのパフォーマンスを重要視する流れにあります。デバイスやブラウザ自体の性能が向上していることもあり、確かにパフォーマンスは向上していますが、一方でWebVRなどさらなるパフォーマンスを必要とするコンテンツが増えてきていることも確かです。今後はコンテンツによってパフォーマンス向上のためのテクニックを見極めることも大事になってくるのかもしれません。