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

はじめに

HTML5 の多くは、これまで JavaScript ライブラリを通じて実現してきたコンポーネントや技術をネイティブ ブラウザでサポートすることを目的としています。これらの機能がある場合は、それを使用することで、ユーザー エクスペリエンスを大幅に向上させることができます。このチュートリアルでは、Yahoo の Exceptional Performance サイト、Google の Page Speed のドキュメントLet's make the web fast のサイトで実施した優れたパフォーマンスに関する調査は要約しません。代わりに、HTML5 と CSS3 を導入してウェブアプリの応答性を高める方法に焦点を当てます。

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

Cookie は長年にわたりユニークユーザーのデータの追跡に使用されてきましたが、Cookie には深刻なデメリットがあります。最大の欠点は、すべての Cookie データがすべての HTTP リクエスト ヘッダーに追加されていることです。これにより、特に XHR では、応答時間に測定可能な影響が及ぶ可能性があります。そのため、Cookie のサイズを小さくすることをおすすめします。HTML5 では、Cookie の代わりに sessionStoragelocalStorage を使用することもできます。

この 2 つのウェブ ストレージ オブジェクトを使用して、セッション中または無期限にユーザーデータをクライアントサイドで保持できます。これらのデータが、どの HTTP リクエストでもサーバーに転送されるわけでもありません。Cookie を廃止できる API があります。次の 2 つの API では、代わりに Cookie を使用しています。

// 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 つの状態を視覚的に遷移させることができます。テキストの影、位置、背景、色の操作など、ほとんどのスタイル プロパティは移行できます。: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 のハードウェア アクセラレーションが発表されました。バージョン 5 では Safari でハードウェア レベルのアクセラレーションが追加されました。(かなり早く Mobile Safari に導入されました)。Chromium に Windows 用の 3D 変換とハードウェア アクセラレーションが追加されたばかりですが、他の 2 つのプラットフォームも近日中に提供される予定です。

GPU アクセラレーションは、かなり制限された条件下でのみ機能しますが、切り替えを行う最も一般的な方法は 3D 変換とアニメーションによる不透明度です。やや乱暴ですが、次の手順で有効にすることができます。

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

ただし、保証される保証はありません。:) ハードウェア アクセラレーションをサポートおよび有効にすると、GPU 合成によるアニメーション移動、回転、スケーリング、不透明度が確実に滑らかになります。GPU で直接処理できるという利点があり、レイヤ コンテンツを再描画する必要はありません。ただし、ページのレイアウトに影響するプロパティについては、依然として比較的低速です。

ヒント 7: CPU を多用するオペレーションの場合、ウェブワーカーは

ウェブワーカーには、2 つの大きなメリットがあります。1)高速である。2)ユーザーがタスクをこなしても、ブラウザは応答性を維持します。実際のワーカー向け HTML5 スライド資料をご覧ください。 Web Worker は、次のような状況で使用できます。

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

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

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

ヒント 9: 重い画像スプライトを要求するのではなく、CSS3 効果を使用する

CSS3 には、画像で視覚的デザインを正確に表現する代わりに、さまざまな新しいスタイル設定が可能になります。2K の画像を 100 バイトの CSS で置き換えることは非常に効果的で、さらに別の HTTP リクエストを削除することは言うまでもありません。知っておくべきプロパティをいくつか紹介します。

  • 線形グラデーションと放射グラデーション
  • 角が丸い場合の枠線の半径
  • ドロップ シャドウとグローのボックス シャドウ
  • RGBA(アルファの不透明度)
  • 回転の変換
  • CSS マスク

たとえば、グラデーションを使って洗練されたボタンを作成したり、sans-images のさまざまな効果を再現したりできます。ブラウザはこれらのほとんどをサポートしており、Modernizr などのライブラリを使用して、この機能をサポートしていないブラウザを検出し、フォールバックとして画像を使用することができます。

ヒント 10: WebSocket は XHR よりも少ない帯域幅でより高速な配信を実現する

WebSockets は、Comet の人気が高まっていることを受けて設計されました。Comet over XHR モデルではなく、WebSocket を使用することには確かに利点があります。

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

参考情報

測定とパフォーマンスに関する推奨事項については、Firefox の拡張機能である Page SpeedYSlow を必ず使用してください。さらに、Speed Tracer for ChromeDynaTrace Ajax for IE を使用すると、より詳細なレベルの分析のログを記録できます。