コンテンツへスキップ

WebAssemblyはどれくらい速いのか

WebAssembly(WASM)はWebブラウザ上で動くプログラムです。JavaScriptとの違いはコンパイルされた実行ファイルであることで、JavaScriptのようにパースする必要がないので高速に処理されます。

高速とは言っても、どれくらい速いのか実行してみないと分からないでしょう。そこで試した結果を紹介します。

フィボナッチ関数を実行する

フィボナッチ関数はJavaScriptで書くと次のように表現されます。

例えば5のフィボナッチ数は8、6のフィボナッチ数は13になります。小さな数であれば一瞬で求められますが、40くらいの数字になると時間がかかるようになります。同じ関数をRustで書くと次のようになります。

計算する

では実際に計算を行ってみた結果です(macOS Safariでの実行結果。ハードウェアの性能によって数値は異なります)。単位はmsです。

  JavaScript WASM
20 2 1
30 69 4
40 6,733 423
42 17,356 1,061
44 46,195 2,839

この結果から分かるのは、少ない数であればJavaScriptもWebAssemblyも殆ど変わりませんが、40以上になるとWebAssemblyが圧倒的に高速になります。50になるとJavaScript側で処理するのは現実的ではないでしょう。フィボナッチ関数に限らず、リストのソート処理であったり、ループ処理などはWebAssemblyの方が効率的なはずです。


WebAssemblyではネットワーク関数が使えない、DOMが扱えないと言った制限がありますが(現在解消されようとしています)、計算処理の速度においては使わない手はありません。開発できる言語はRustに限らず、様々な言語があります。ぜひWebAssemblyの活用を検討してください。

PWAハンズオンを開催しました

PWA(Progressive Web Apps)というキーワードに注目が集まっていますが、実際に取り組む機会がないという方は多いようです。そこでhifiveのTodoアプリをベースに、PWAを体験してもらうハンズオンを開催しました。

コンテンツはGitHubにあります

体験してもらったハンズオンコンテンツはhifivemania/pwahandsondocsに置いてあります。内容としてはこれに合わせて進めたので、オンラインで体験してもらうことも可能です。ハンズオンはこの資料を基に各自のペースで進めてもらうのですが、何か分からないところがあればすぐにフォローしてもらえるのが参加メリットになります。

hifiveとは

ハンズオンの最初にhifiveとは何かを紹介しました。今回のハンズオンではTodo投稿機能などにおいてhifiveを使っていますが、PWAを扱う上では必須ではありません。しかしビジネスとしてWebシステムを開発する上で問題になりがちな要員確保や中長期的なメンテナンスという問題においてhifiveは最適な解決策になるべく開発を進めています。これはPWAにおいて役立つ場面があるはずです。

hifive – HTML5企業Webシステムのための開発プラットフォーム – hifive

ハンズオン開始

ハンズオンは前述の通り、各自のペースで行ってもらいます。そのため、ハンズオン中は基本的に静かで黙々と作業されています。進めていく中でつまずくポイントは幾つも、人によっても異なるのでそれらを随時フォローアップしていきました。

今回体験してもらったもの

今回のハンズオンではPWAにおいて以下の要素を体験してもらいました。

  • オンライン/オフライン対応
  • アプリ化
  • Webプッシュ通知

PWAでは他にも要素技術があります。今回のを基礎として、自社やクライアント向けの開発に役立てて欲しいと思います。

次回開催について

PWAハンズオンは好評いただいており、すでに2回目が設定済みです。会場は今回と同じく渋谷のhoops link tokyoさんになります。日時は4月12日(金)19時からです。PWAを体験してみたい方はぜひご参加ください!

PWAハンズオン – connpass

Workboxのプラグインについて

PWAにおいて肝となるのがキャッシュです。あるURLにアクセスした時にコンテンツを返却するのがキャッシュですが、HTML5におけるCACHE APIはすべてプログラムから操作しなければならず、実装が大変です。

そこで使ってみたいのがWorkboxになります。Google製のPWAにおけるキャッシュコントロールを便利にしてくれるライブラリになります。今回はWorkboxに対応しているプラグインと、その機能を紹介します。

workbox.backgroundSync.Plugin

ネットワークがオフラインだった場合、オンラインになったタイミングで同期してくれます。queueArgsとしてキューに送信する引数を指定します。

workbox.broadcastUpdate.Plugin

キャッシュを更新した時に、それをメッセージングしてくれます。メインスレッドのJavaScriptで受け取ったならば、表示を更新したりユーザに再読込を促したりできるでしょう。チャンネル名を指定します。

オプションは以下の通りです。

  • headersToCheck
    チェックするヘッダーを指定。
  • source
    データ元のソースを指定。

workbox.cacheableResponse.Plugin

キャッシュする際のヘッダーレスポンスを指定。

オプションは以下の通りです。

  • statuses
    キャッシュするHTTPレスポンスコードを配列で指定。
  • headers
    キャッシュするHTTPレスポンスヘッダーをオブジェクトで指定。

workbox.expiration.Plugin

キャッシュに有効期限を付けられるプラグイン。

オプションは以下の通りです。

  • maxEntries
    最大の登録数。
  • maxAgeSeconds
    有効期限。秒で指定。
  • purgeOnQuotaError
    容量制限に引っかかった場合はエラーにするかどうか。

workbox.rangeRequests.Plugin

HTTPのRangeへのアクセス対応用です。分割ファイルをリクエスト、キャッシュするのに使います。

自作プラグインの作り方

プラグインは以下の5つのメソッドを持ったオブジェクトになります。

  • cacheWillUpdate
  • cacheDidUpdate
  • cachedResponseWillBeUsed
  • requestWillFetch
  • fetchDidFail

Workboxを使えばキャッシュのコントロールが柔軟になります。プラグインを使ったり、自作することでより簡単に実装できるようになるでしょう。ぜひ使い方を覚えましょう。

Workbox | Google Developers

Workboxでキャッシュの有効期限を付ける

PWAのCACHE APIにおいて問題になりがちなのが、キャッシュが更新されないということです。基本的にプログラム側から削除や更新しない限り、キャッシュは恒久的に残り続けます。

Googleが開発するWorkboxを使えば、キャッシュに有効期限を設けられます。そうすれば一定時間経過すれば自動的にキャッシュがなくなってコンテンツがリフレッシュされます。

有効期限の付け方

有効期限を設ける時には、キャッシュ作成時に workbox.expiration.Plugin を指定します。

これを見て分かる通り、キャッシュ名を指定して作成するので、有効期限はキャッシュ名単位になります。一般的にはキャッシュ名を一つで運用してしまいがちですが、リソースの種類によって有効期限を変えるのは面白そうです。


キャッシュコントロールの難しさがPWAの導入を遅らせているとも言えます。Workboxを使って、キャッシュを適切にコントロールしてください。

Workbox  |  Google Developers

Workboxを使ってPWAのキャッシュを作成する

Googleが提供するWorkboxはService Workerを使う上で必須とも言える機能を提供してくれます。特にキャッシュ周りの面倒な操作を手軽に行ってくれるのが利点です。

今回はそんなWorkboxでキャッシュを作成する方法を紹介します。

インストール

Workboxのインストールはローカルにファイルを設置することもできますが、importScriptsでリモートファイルを指定するのが最も簡単です。

これで workbox というグローバル変数が定義されます。

パターンで登録する

一般的にキャッシュを作成する場合、URL単位で指定します。しかしWorkboxの場合は正規表現パターンで指定できます。

このように定義することで、 *.js のリクエストに対してはキャッシュファーストで返してくれるようになります。他にも workbox.strategies.networkFirst()workbox.strategies.staleWhileRevalidate() も用意されています。


キャッシュを正規表現で指定することで、多数のファイルをまとめてキャッシュ化できます。特定ファイルはキャッシュしないというポリシーであっても、正規表現で指定すれば問題ありません。WorkboxはService Worker利用時には欠かせないツールと言えます。ぜひ使いこなしてください!

Workbox  |  Google Developers

PWAでキャッシュされているファイルを確認する

PWAではService WorkerのCACHE APIを使ってファイルをキャッシュできます。それを使えばオフライン時にもリソース(画像やJavaScriptファイルなど)を返せるので、ネットワークに繋がっていなくともWebアプリケーションが使い続けられます。

PWAを開発している際に、ファイルがキャッシュされているか、さらにキャッシュされてしまったファイルを簡単に削除する方法を紹介します。

キャッシュファイルの確認

Google Chromeを使っている場合、開発者ツールのApplicationタブにあるCache Storageからキャッシュされているコンテンツであったり、キャッシュされている内容の確認もできます。

これを使えば正しくキャッシュされているかどうか、すぐに確認できます。

キャッシュの削除

キャッシュの一覧を右クリックすると、リフレッシュと削除が表示されます。プログラムでキャッシュを更新することもできますが、開発中であれば開発者ツールから行うのが簡単です。


CACHE APIは非常に強力で、キャッシュの更新や削除をしないと恒久的に残り続けてしまいます。開発中、最初から更新や削除の仕組みがある訳ではないと思いますので、開発者ツールを使う方法を覚えておくと便利です。

GoではじめるWebAssebmly その5「ウィンドウオブジェクト、localStorageを使う」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はさらに面白い、ウィンドウオブジェクトやlocalStorageをWebAssemblyから使ってみます。

オンライン、オフラインを検知する

Webアプリケーションのネットワーク状態を受け取るには window オブジェクトの online または offline イベントを使います。これももちろんGoのWebAssemblyの中に記述できます。

そしてオンライン、オフラインの値は navigator.onLine で取れますので、この値も使います。

 

これでWebAssembly側でもオンライン、オフラインの判定ができるようになります。

localStorageを使う

さらにWebブラウザとWebAssemblyでデータの送受信をする際に使ってみたいのがlocalStorageを経由したデータ授受です。

 

 

このようなコードで localStorage に触って、データをセットしたり、値の取得を行えます。localStorageの場合、setItemやgetItemではなくSet/Getで値の授受ができるのが特徴です。 localStorage.Call("setItem", "Hello", "World") ではうまくいきませんが、 localStorage.Get("getItem", "JavaScript") は利用できます。


syscall/js は非常によくできており、同時に利用する wasm_exec.js と組み合わせることでWebAssemblyからDOMやJavaScriptのAPIを透過的に扱えます。ちょっとした使い方さえ覚えてしまえばJavaScriptと変わらず使えるようになりそうです。

オンライン、オフライン判定などWebAssemnly単体では難しいことも容易に実現できます。ぜひGoでWebAssemblyを使ってみてください。