HTML5 でウェブアプリを高速化するためのおすすめの方法

はじめに

HTML5 の多くは、これまで JavaScript ライブラリで実現してきたコンポーネントと手法にネイティブ ブラウザ サポートを提供することを目的としています。これらの機能が利用可能な場合は、それらを使用してユーザーに高速なエクスペリエンスを提供できます。このチュートリアルでは、Yahoo の優れたパフォーマンスのサイトや、Google のページ速度に関するドキュメントウェブの高速化サイトに掲載されている優れたパフォーマンスに関する調査結果をまとめることはありません。代わりに、HTML5 と CSS3 を今日から活用してウェブアプリの応答性を高める方法について説明します。

ヒント 1: Cookie の代わりにウェブ ストレージを使用する

Cookie は長年にわたってユニーク ユーザーデータの追跡に使用されてきましたが、重大な欠点があります。最大の問題は、すべての Cookie データがすべての HTTP リクエスト ヘッダーに追加されることです。これにより、特に XHR の実行中にレスポンス時間に測定可能な影響が生じる可能性があります。そのため、Cookie のサイズを小さくすることをおすすめします。HTML5 では、Cookie の代わりに sessionStoragelocalStorage を使用することで、より優れた方法でユーザーの状態を保持できます。

これらの 2 つのウェブ ストレージ オブジェクトを使用すると、セッションの期間中または無期限にユーザーデータをクライアントサイドに保持できます。データは、すべての HTTP リクエストを介してサーバーに転送されることはありません。Cookie を削除できる API があります。以下に、Cookie をフォールバックとして使用する両方の API を示します。

// if localStorage is present, use that
if (('localStorage' in window) && window.localStorage !== null) {

  // easy object property API
  localStorage.wishlist = '["Unicorn","Narwhal","Deathbear"]';

} else {

  // without sessionStorage we'll have to use a far-future cookie
  //   with document.cookie's awkward API :(
  var date = new Date();
  date.setTime(date.getTime()+(365*24*60*60*1000));
  var expires = date.toGMTString();
  var cookiestr = 'wishlist=["Unicorn","Narwhal","Deathbear"];'+
                  ' expires='+expires+'; path=/';
  document.cookie = cookiestr;
}

ヒント 2: JavaScript アニメーションの代わりに CSS 遷移を使用する

CSS 遷移を使用すると、2 つの状態間の魅力的な視覚的な遷移を実現できます。ほとんどのスタイル プロパティは、text-shadow、位置、背景、色の操作など、遷移できます。:hover などの疑似セレクタの状態への遷移や、HTML5 フォームの :invalid:valid からの遷移を使用できます(フォームの検証状態の例)。ただし、より強力で、要素にクラスを追加したときにトリガーできます。

div.box {
  left: 40px;
  -webkit-transition: all 0.3s ease-out;
     -moz-transition: all 0.3s ease-out;
       -o-transition: all 0.3s ease-out;
          transition: all 0.3s ease-out;
}
div.box.totheleft { left: 0px; }
div.box.totheright { left: 80px; }

tothelefttotheright のクラスを切り替えることで、ボックスを移動できます。このコード量を JavaScript アニメーション ライブラリのコード量と比較してみてください。明らかに、CSS ベースのアニメーションを使用すると、ブラウザに送信されるバイト数が大幅に減ります。また、GPU レベルのアクセラレーションにより、これらの視覚的な遷移は可能な限りスムーズになります。

ヒント 3: サーバー ラウンドトリップの代わりにクライアントサイド データベースを使用する

Web SQL DatabaseIndexedDB は、クライアントサイドにデータベースを導入します。XMLHttpRequest またはフォーム送信を介してサーバーにデータを投稿する一般的なパターンではなく、これらのクライアントサイド データベースを利用できます。HTTP リクエストの削減はすべてのパフォーマンス エンジニアの主な目標であるため、これをデータストアとして使用すると、XHR やフォーム投稿を介してサーバーに送信する多くのリクエストを削減できます。localStoragesessionStorage は、フォーム送信の進行状況をキャプチャする場合などに使用できます。クライアントサイド データベース API よりもはるかに高速です。たとえば、データグリッド コンポーネントや数百件のメッセージを含む受信トレイがある場合、データをローカルのデータベースに保存すると、ユーザーが検索、フィルタ、並べ替えを行う際に HTTP ラウンドトリップを節約できます。友だちのリストやテキスト入力の自動補完は、キー入力ごとにフィルタできるため、ユーザー エクスペリエンスが大幅に向上します。

ヒント 4: JavaScript の改善によりパフォーマンスが大幅に向上

JavaScript 1.6 では、配列プロトタイプに多くのメソッドが追加されました。現在、IE を除くほとんどのブラウザで利用できます。次に例を示します。

// Give me a new array of all values multiplied by 10.
[5, 6, 7, 8, 900].map(function(value) { return value * 10; });
// [50, 60, 70, 80, 9000]

// Create links to specs and drop them into #links.
['html5', 'css3', 'webgl'].forEach(function(value) {
  var linksList = document.querySelector('#links');
  var newLink = value.link('http://google.com/search?btnI=1&q=' + value + ' spec');
  linksList.innerHTML +=  newLink;
});


// Return a new array of all mathematical constants under 2.
[3.14, 2.718, 1.618].filter(function(number) {
  return number < 2;
});
// [1.618]


// You can also use these extras on other collections like nodeLists.
[].forEach.call(document.querySelectorAll('section[data-bucket]'), function(elem, i) {
  localStorage['bucket' + i] = elem.getAttribute('data-bucket');
});

ほとんどの場合、これらのネイティブ メソッドを使用すると、for (var i = 0, len = arr.length; i &lt; len; i++) などの一般的な for ループよりも大幅に高速化できます。ネイティブ JSON 解析(JSON.parse() 経由)は、これまで使用していた json2.js ファイルに代わるものです。ネイティブ JSON は外部スクリプトを使用するよりもはるかに高速で安全です。IE8、Opera 10.50、Firefox 3.5、Safari 4.0.3、Chrome ではすでに使用できます。ネイティブ String.trim は、長い JS の同等機能よりも高速であるだけでなく、より正確である可能性が高いという点でも、良い例です。これらの JavaScript の追加機能は、技術的には HTML5 ではありませんが、最近利用可能になるテクノロジーの範疇に含まれます。

ヒント 5: オフライン アプリだけでなく、公開サイトにもキャッシュ マニフェストを使用する

2 年前、WordPress は Google Gears を使用して WordPress Turbo という機能を追加しました。基本的に、管理パネルで使用される多くのリソースがローカルにキャッシュに保存され、ファイルへのアクセスが高速化されました。この動作は、HTML5 の applicationCache と cache.manifest で再現できます。アプリキャッシュには、Expires ヘッダーを設定するよりも若干の利点があります。キャッシュに保存できる静的リソースを示す宣言ファイルを作成するため、ブラウザはそれを大幅に最適化できます。使用前にキャッシュに保存することもできます。サイトの基本構造をテンプレートとして考えてみましょう。データは変更される可能性がありますが、その周囲の HTML は通常、かなり一貫しています。アプリ キャッシュを使用すると、HTML を一連の純粋なテンプレートとして扱い、cache.manifest を介してマークアップをキャッシュに保存し、JSON をワイヤー経由で配信してコンテンツを更新できます。このモデルは、iPhone や Android のネイティブ ニュースアプリの動作と非常によく似ています。

ヒント 6: ハードウェア アクセラレーションを有効にして視覚的なエクスペリエンスを向上させる

主要なブラウザでは、多くのビジュアル オペレーションで GPU レベルのアクセラレーションを利用できます。これにより、高度な動的ビジュアル オペレーションを大幅にスムーズにできます。ハードウェア アクセラレーションは Firefox MinefieldIE9 で発表されており、Safari ではバージョン 5 でハードウェア レベルのアクセラレーションが追加されています。(Mobile Safari ではずっと以前から利用可能でした)。Chromium では、Windows 向けの 3D 変換とハードウェア アクセラレーションが追加されました。他の 2 つのプラットフォームにも近日提供される予定です。

GPU アクセラレーションは、かなり制限された一連の条件下でのみ開始されますが、3D 変換とアニメーション化された不透明度が、スイッチをトリップする最も一般的な方法です。ややハッキング的な方法ですが、目立たない方法でオンにするには、次の手順を行います。

.hwaccel {  -webkit-transform: translateZ(0); }

ただし、保証されるものではありません。ハードウェア アクセラレーションがサポートされ、有効になっている場合、GPU 合成により、アニメーション化された移動、回転、スケーリング、不透明度がよりスムーズになります。GPU で直接処理されるため、レイヤ コンテンツの再描画は必要ありません。ただし、ページのレイアウトに影響するプロパティは、比較的遅くなります。

ヒント 7: CPU 使用率の高いオペレーションでは、Web Worker が効果的

ウェブワーカーには 2 つの大きなメリットがあります。1 つは高速であることです。2)タスクを処理している間も、ブラウザは応答し続けます。HTML5 スライド デッキで、Workers の動作をご覧ください。次のような状況では、Web Worker を使用できます。

  • 長いドキュメントのテキストの書式設定
  • 構文のハイライト表示
  • 画像処理
  • 画像合成
  • 大規模な配列の処理

ヒント 8: HTML5 フォームの属性と入力タイプ

HTML5 では、textpasswordfile のセットから searchtelurlemaildatetimedatemonthweektimedatetime-localnumberrangecolor を含む新しい入力タイプが導入されました。これらの機能のブラウザ サポートはブラウザによって異なり、現在 Opera でほとんどの実装が完了しています。機能検出を使用すると、ブラウザがネイティブでサポートされているかどうか(日付選択ツールや色選択ツールなどの UI が提供されるかどうか)を判断できます。サポートされていない場合は、引き続き JS ウィジェットを使用してこれらの一般的なタスクを実行できます。タイプに加えて、通常の入力フィールドに便利な機能がいくつか追加されています。入力 placeholder は、クリックすると消去されるデフォルトのテキストを表示します。autofocus は、ページの読み込み時にカーソルをフォーカスするため、そのフィールドをすぐに操作できます。入力検証も HTML5 で導入された機能の 1 つです。required 属性を追加すると、そのフィールドが入力されるまでブラウザでフォームを送信できなくなります。また、pattern 属性を使用すると、テストする入力のカスタム正規表現を指定できます。無効な値はフォーム送信をブロックします。この宣言型構文は、ソースの可読性の向上だけでなく、必要な JavaScript を大幅に削減できるという大きなアップグレードです。これらの機能がネイティブでサポートされていない場合は、機能検出を使用してフォールバック ソリューションを提供できます。ネイティブ ウィジェットを使用すると、これらのウィジェットを表示するために必要な重い JavaScript と CSS を送信する必要がないため、ページの読み込みが速くなり、ウィジェットの応答性が向上する可能性があります。これらの入力機能の強化をお試しになるには、HTML5 スライド デッキをご覧ください。

ヒント 9: サイズの大きい画像スプライトをリクエストする代わりに、CSS3 エフェクトを使用する

CSS3 では、画像を使用して視覚デザインを正確に表現する代わりに、さまざまな新しいスタイル設定が可能になりました。2, 000 バイトの画像を 100 バイトの CSS に置き換えることは大きなメリットです。さらに、HTTP リクエストも 1 つ削除できます。次のようなプロパティについて理解しておいてください。

  • 線形グラデーションと円形グラデーション
  • 角丸の Border-radius
  • ドロップ シャドウとグローの box-shadow
  • アルファ不透明度に RGBA を使用する
  • 回転の変換
  • CSS マスク

たとえば、グラデーションを使用して洗練されたボタンを作成したり、画像を使用せずに他の多くの効果を再現したりできます。これらの機能のほとんどはブラウザで十分にサポートされています。Modernizr などのライブラリを使用して、これらの機能をサポートしていないブラウザを検出し、フォールバック ケースで画像を使用することもできます。

ヒント 10: WebSocket で XHR よりも少ない帯域幅で高速配信

WebSockets は、Comet の人気が高まっていることに対応して設計されました。XHR を介した Comet モデルではなく、WebSocket を使用するメリットは確かにあります。

WebSocket はフレーミングが非常に軽量であるため、消費する帯域幅は XHR よりも軽量です。一部の報告では、ワイヤーを介して送信されるバイト数が 35% 削減されています。また、送信されるメッセージの量が多いほど、メッセージ配信のパフォーマンスの差は顕著になります。このテストでは、XHR の合計時間が WebSocket よりも 3, 500% 長く記録されています。最後に、Ericsson Labs が WebSocket のパフォーマンスを検討したところ、処理要件が大幅に増加しているため、HTTP 経由の ping 時間が WebSocket 経由の ping 時間の 3 ~ 5 倍であることがわかりました。WebSocket プロトコルがリアルタイム アプリケーションに明らかに適しているという結論に至りました。

参考情報

測定とパフォーマンスに関する推奨事項については、Firefox 拡張機能の Page SpeedYSlow を使用することをおすすめします。さらに、Chrome 用 Speed TracerIE 用 DynaTrace Ajax では、より詳細なレベルの分析ロギングが可能です。