ここ数年のうちに、人々が利用するメインコンピューターは、デスクトップからモバイルへと移りました。
少ないハードウェアリソース、不安定なネットワーク、逼迫するバッテリー消費、シンプルなユーザインタフェース、開発者はこうした制約の中で、Webサイトを制作することが求めらるようになりました。Webのパフォーマンスに関する考え方も大きく変化があったのですが、我々は具体的に何を基準にし、どの程度にチューンすれば良いのでしょう?その答えが、パフォーマンスモデル「RAIL」にあります。
RAILは、開発者向けカンファレンス「Google I/O 2015」にて発表されました。厳密にはI/Oが初というわけではありませんが、実に2桁近いセッションでこのキーワードが紹介されています。今後は一般的になっていくのでしょう。
モバイル時代のWebのパフォーマンスモデル
一見するとRubyと関係しそうですが、全くコンテキストの異なるキーワードです。RAILとは、モバイル時代のWebのパフォーマンスの4大要素、Response、Animation、Idle、Loadの頭文字からとった略称です。それぞれの項目が、一体何を意味しているのか紹介してみます。
1. R : Responseは100ms未満になるように!!
ユーザがWebページに対して何かしらの操作を行った場合、その反応は100ms未満で起きるような作りにしましょう。決済完了ボタンなど、速くし過ぎることで「失敗してしまった感」を与えるケースもありますが、概ねこの考えで間違いはないでしょう。
2. A : Animationは16ms毎になるように!!
Webページ上で何かしらビジュアル面で動きを与える場合、その動きは16ms毎で更新されるような作りにしましょう。毎フレームごとにJavaScriptを呼び出す場合は出来る限りGCを避けるようにしたり、CSSを活用するなど、アニメーションを速くする対策を施しましょう。
3. I : Idleは100ms未満で起きるように!!
Webページ上でJavaScriptを活用して何かしらのスクリプトを動かす場合は、100ms未満でメインスレッドにも処理が行えるような余裕(=Idle)を持たせる作りにしましょう。JavaScriptの処理実行時は、ユーザの操作をブロックしてしまうため、適度にメインスレッドへ処理が帰るように工夫が必要です。これは1のResponseと、同じ理由と言えます。
4. L : Loadは1000ms未満に終わるように!!
ハイパーリンクやサブミットボタンが押下された時のWebページ読み込みは、アクションを起こしてからDOM生成までを1000ms未満で完了するように作りましょう。
守れないとどうなるのか?
ここまで理由もなく「◯◯秒未満で!」と繰り返してきましたが、一応は根拠と呼べるものがあります。それが、以下2つの定説です。
アニメーション反応応答と人間の認識
The Illusion of Motion - Paul Bakaus' blog
滑らかなアニメーションが行える周期は、一秒間に60回の更新が行われた状態、ということになります。また、秒間24回よりも小さな更新で、ちらつきを感じるようになるとも言われています。
アクション待ちに対する人間の心理
O'Reilly Media - Technology and Business Training
すぐに応答したと感じられるのは100ミリ秒であり、また1000ミリ秒以上経過すると、心理的なコンテキストが変わってしまいます。パフォーマンスコミュニティにおいては「250ミリ秒という時間がユーザのエンゲージメントにとって重要」という認識を持っているようです…が、少なくとも、ResponseとIdleのようなWebページ上での部分的な反応については100ミリ秒で、LoadのようなWebページの内容が完全に変わってしまうような反応についても、心理的コンテキストが変わらない1000ミリ秒で次の情報へ意識を導かなくてはいけない、ということが言えるでしょう。
RAILに足りていないこと
RAILはあくまで、従来のWebサイトのコンテキストで語られています。しかし実態として、Android Chromeはネイティブアプリと同じユースケースで活用できるよう、機能の拡充が進められています。特にService Worker + Notificationの登場で、Webにブラウザを閉じた後にも実行し続けるという、まさにモバイルのネイティブのようなライフサイクルを与えることができるようになりました。Webサイトというより、ネイティブアプリに近い課題が生じることになります。
RAILには含まれていない重要なポイントとしては、「バッテリー消費」なんかが挙げられるでしょう。バッテリー消費で一番問題になるのはディスプレイ、二番目はネットワークと言われ、特に後者については様々なノウハウがあります。Androidアプリにおいても、断続的に飛ばしたいXHRをBatch化させたり、pollingを廃するなど、ネットワークインタフェースの利用時間を減らすような努力が求められています。ブラウザ上で動くアプリも、ブラウザを閉じている間までネットワークの利用が可能というのであれば、当然ですが意識しなくてはいけません。既にApache Cordovaなんかでは、こういうTIPSが利いていたりするのですが…
少なくともWebサイトにおいては十分価値のある考え方なので、ぜひとも、RAILに沿って実践してみると良いでしょう。興味がありましたら、「High Performance Browser Networking」の著者であるIlya Grigorikのスライドをチェックしてみてください。
「Fast ASP.NET Websites」の著者であるDean Alan Hume氏のプレゼンスライドも参考になるでしょう。こちらは具体的な戦略まで書かれているため、入り口としては非常に有益です。