[SkyDrive] HTML5 による SkyDrive のユーザー エクスペリエンス高速化への取り組み

※本記事は、Inside Windows Blog の抄訳です。

 先日リリースされた SkyDrive の新バージョンはもうお試しいただけたでしょうか。Web エクスペリエンスのパフォーマンスが飛躍的に向上し、デザインがすっきりとしたことに気付かれた方も多いと思います。
この記事では、新しい SkyDrive の Web エクスペリエンスを高速化するために行った取り組みについてご紹介します。

新しい SkyDrive アーキテクチャを構築するにあたって私たちが目指す最終的な目標は、HTML5 と Internet Explorer 9 などの最新ブラウザーの機能の活用によって、ページ読み込みの削減とクリック操作を行った際の高速化を実現することです。

以前のバージョンの SkyDrive はサーバーによるレンダリング アーキテクチャをベースとしていたため、SkyDrive のページでクリック操作を行うたびに、サーバーによって生成されたページ全体の読み込みが発生していました。ページ読み込みは非常に時間のかかる処理です。クライアント側のキャッシュがなく、クライアントとサーバーの間で頻繁にデータがやり取りされるので、完了するまでに数秒間かかってしまいます。つまり、ユーザーが何か操作をするたびに 2 ~ 3 秒という時間がかかるので、理想とはかけ離れた状況でした。これは、古いブラウザーを使用しているユーザーに対応するための “最小公分母” 的なアプローチでした。

現在では数千万人に上るユーザーが最新ブラウザーにアップグレードしているので、新しい機能を活用し、インテリジェントな AJAX アーキテクチャに移行することが可能になりました。AJAX のパフォーマンスを向上させる鍵は、インテリジェントなクライアント ネットワークを利用することにあります。これはパフォーマンスの最大のボトルネックがクライアント ネットワークにあることが多いためです。マイクロソフトでは、インテリジェントなクライアント ネットワークの利用に関して、次の 4 つの点に注目しました。

  1. クライアント サーバーの要求の数を減らす (クライアント側のキャッシュ)
  2. 各要求のペイロードのサイズを縮小する (必要なものだけを取得し、プロトコルを圧縮する)
  3. 要求の送信経路を短縮する (サーバーやコンテンツ配信ネットワークをユーザーの近くに配置する)
  4. 各要求を最大限に活用する (バッチ処理やプリフェッチを利用する)

それでは、実際に行った開発作業を詳しく見ていきましょう。

ページ読み込みを削減する

この新しい SkyDrive アーキテクチャは多くの点で AJAX を思い出させますが、事実、AJAX をベースとしています。マイクロソフトが最初に AJAX に移行しようとしたのは 10 年ほど前でしたが、当時実現された Web エクスペリエンスは非常に遅いものでした。これは、ブラウザーの処理速度が遅かったこと、JavaScript の処理が不安定であったこと、エンドユーザーのネットワーク接続が低速であったこと、サイズが大きく解析に時間のかかる XML を使用していたこと、クライアント側のキャッシュがなかったことなど、さまざまな問題が重なっていたことが原因でした。

現在最も新しいブラウザーは 8 年前に比べて大幅に高速化され、JavaScript の実行も安定しています。また、プロトコル形式は軽量な JSON に切り替えられました。さらに、クライアント側のキャッシュ機能が向上し、非同期的にデータ要求の実行を継続できるので、サーバーの応答を待っている間に Web エクスペリエンスが中断されることもありません。これを主要なブラウザーすべてで完全に実現することは容易ではありませんが、それが私たちの目標です。

ブラウザーで SkyDrive に移動すると、今でもページの読み込みが発生します。SkyDrive に最初にアクセスしたとき (= 最初のページ読み込みを PLT1 と呼びます) は、それ以降のアクセス (PLT2) よりも時間がかかります。これは、コンテンツ配信ネットワークから静的リソースのセットをダウンロードしてクライアントでキャッシュに保存する必要があるためです。

通常、AJAX ではクライアント側での処理が多くなるため、クライアント側で必要なリソースも増加します。PLT1 の処理を向上させるために、いくつか工夫を施しました。たとえば、ユーザーが login.live.com ページを表示したときに SkyDrive のリソースを事前にダウンロードして、SkyDrive にアクセスするまでにクライアントに保存されるようにしました。また、SkyDrive のエクスペリエンスですぐに必要ではない特定のリソースのダウンロードを後回しにしています (この一例として WebIM があります)。

さらに、ページ読み込みを最適化するために、ASP.NET Web サーバーからの HTML ページの生成方法も見直しました。以前はページ全体が生成されるまで待ってから、HTML ページをブラウザーに返していました。SkyDrive のメイン Web ページの場合、生成するには複数のバックエンド システムを呼び出す必要があり、ブラウザーに HTML ページを返す処理は、これらのバックエンドの呼び出しが完了してから行っていました。

この点を改良して、サーバー上で HTML フラグメントが用意されると同時に、フラッシュしてブラウザーに返すようにしました。これによる大きなメリットとして、ブラウザーではスクリプトや CSS を参照する HTML フラグメントを瞬時に取得でき、それらのリソースのダウンロード (キャッシュに存在しない場合) を、サーバーで実行されている他の処理 (バックエンドの呼び出しなど) と並行して開始できるようになりました。この考え方は、分散システム (クライアントとサーバー) 全体で、より多くの処理 (特にネットワーク呼び出し) を並行して実行するというものです。

4466_SkyDrive-1_thumb_60E4BA03

新しい SkyDrive でも、フォルダーのアクセス許可の編集、ファイルの削除、アルバム内の写真の整列などの一部の操作では、ページ全体の読み込みが必要です。これまで、SkyDrive のファイルの参照と写真の表示のエクスペリエンスのみを新しい AJAX アーキテクチャに移行しましたが、将来の更新ではサイトの残りの部分についても移行する予定です。

HTTP/JSON データ アクセス プロトコル

述のように、最大の変更点は、SkyDrive のファイル参照エクスペリエンスを AJAX に移行したことであり、SkyDrive のユーザー エクスペリエンスはクライアントでレンダリングされます。これによって、ページ全体の読み込みが減少し、ブラウジングが瞬時に行われるようになりました。このクライアント駆動型のクライアント レンダリング モデルに移行するには、SkyDrive のユーザー データ (HTML ではない) をサーバーからフェッチする機能が必要だったため、HTTP と JSON に基づくデータ アクセス プロトコルを構築しました。

このデータ アクセス プロトコルによって、ユーザーが Web エクスペリエンスで何らかのビュー を選択したときに必要になるユーザーのデータを効率的にフェッチできるようになりました ([School Project] フォルダー内にある 100 個のドキュメントを名前で並べ替えて最初の 20 個を表示するなど)。

このデータ アクセス プロトコルは、並べ替え、フィルタリング、およびページングをサポートしており、API は基本的に Web エクスペリエンスでユーザーが生成できるビューの種類と 1 対 1 で対応しています。重要なのは 1 つのサーバー要求を実行してビューを作成できる点です。

サーバーでは、この API を迅速に実行してデータを返せるようにすることが重要です。データの並べ替え、フィルタリング、ページングをすべて SQL Server データベース層で実行することによって、これを実現しています。以前は、大量のデータの見本を SQL Server から取り出して、ASP.NET サーバー上で操作していましたが、この方法は非効率的でした。最適なのは、必要なデータだけを取り出して返すことができるように、SQL Server の処理能力を利用し、クエリを最適化して実行することです。

前述のように、このデータ アクセス プロトコルにもネットワークで効率のよい JSON データ形式を使用しているので、ブラウザーで高速に解析を実行することができます。ほとんどの場合、1 ページのユーザー データをフェッチするだけなので、多くのデータ要求のサイズは数キロバイトに過ぎず、数ミリ秒以内にデータが返されます (もちろん、エンドユーザーのクライアント ネットワークの帯域幅に依存します)。

このデータ アクセス プロトコルによって返されるデータは、ブラウザーでキャッシュすることができます。クライアント キャッシュによって、エクスペリエンスのパフォーマンスは最大限に引き出されます。データ要求がクライアント キャッシュから取得される場合には、最適な結果が得られます。これによって、エクスペリエンスが高速化するほか、サーバーで以前ほど多くの処理を実行する必要がなくなるため、コスト (使用するサーバー) も削減することができます。次に、ユーザー データをキャッシュする方法について詳しく説明します。

私たちが実行しているもう 1 つの工夫は、ユーザーが最初に SkyDrive にアクセスし、ページ全体が読み込まれるときに、サーバーから返される HTML ページと共に最上位レベルのユーザー データを返すことです。これによって、最上位レベルのユーザー データをフェッチするときに必要だった、サーバーとの 2 回目のやり取りが不要になります。これは、2 つの要求を 1 つの要求にするバッチ処理の良い例です。

リスト ビューの仮想化

以前の SkyDrive の Web エクスペリエンスでは、特定のフォルダーに移動して表示する場合、そのフォルダー内のすべてのファイルが含まれている Web ページをダウンロードしていました。標準的なフォルダーの一例として、SkyDrive に保存されている Windows Phone のカメラ ロール フォルダーがあります。Windows Phone ユーザーのおよそ 25% は、このフォルダーに約 1,000 枚の写真を保存しています。1,000 枚の写真が保存されたカメラ ロール フォルダーを表示したときのエクスペリエンスは非常に遅くなります。

新しい SkyDrive では、仮想化されたリスト ビューのサポートが追加されたので、サイズが大きいフォルダーのビューを効率的に処理できるようになりました。Microsoft Outlook などの多くのクライアント アプリケーションでも、パフォーマンス向上を目的として仮想化されたリスト ビューを使用しているので、多くのユーザーはこの概念になじみがあると思います。

ここで重要なのは、ユーザーが多くのファイルが含まれたフォルダーを表示したときに、ブラウザーの現在の画面に表示するのに必要なデータのみをフェッチして表示している点です。サーバーまたはキャッシュから小さなページのデータ (数キロバイト) をフェッチし、少量の HTML をレンダリングするだけなので、非常に効率的で高速です。もう 1 つの注目すべき改善点は、ブラウザーのスクロール バーを使用して、ユーザーがリストをスクロールできるようにしたことです。ユーザーがスクロールしたときに、動的にデータをフェッチしてリスト ビューをレンダリングするようにしています。これにより、フォルダー内にどれほど多くのファイルがあるかにかかわらず、非常に高速でスムーズなエクスペリエンスが実現されます。

5732_SkyDrive-2_thumb_1C647D2A

仮想化されたリスト ビューをサポートする機能は、ファイルの特定のページをフェッチできるようにする、前述のデータ アクセス プロトコルによって実現されています。この機能をテストするために、SkyDrive でファイル数の多いフォルダーに移動して、Ctrl キーを押しながら End キーを押してみます。高速にスクロールが行われ、フォルダー内の最後のページが即座に表示されます。これは、SkyDrive のストレージ システムがデータベース レベルでこのクエリを迅速に実行できるからです。

クライアント側のキャッシュ

クライアント側のキャッシュは、特定のネットワーク要求を完全に無視し、ローカル コンピューターからデータを取得してユーザー エクスペリエンスを瞬時にレンダリングできるようにするので、優れた Web パフォーマンスを実現するためには不可欠です。クライアントでキャッシュできるデータが増えるほど、パフォーマンスが向上します。

新しい SkyDrive のアーキテクチャでは、2 つのレベルのキャッシュを利用しています。前にも述べましたが、HTTP/JSON アクセス プロトコルに対して行われたすべてのデータ要求は、ブラウザーのキャッシュに保存されます。以前の要求と同じデータ要求が行われた場合、実際にネットワークにアクセスしてサーバーを呼び出す代わりに、ブラウザーのキャッシュからデータが提供されます。これによって、SkyDrive のブラウザー セッション間でユーザー データをキャッシュすることができます。

次の層のキャッシュは、インメモリ データ キャッシュです。このキャッシュは、実行中の SkyDrive セッションについてのみ存在します。またこのキャッシュは、ビュー間の切り替えを高速にするために使用されます。前述のデータ アクセス プロトコルによってデータを要求し、ブラウザーのキャッシュからデータが提供されたら、SkyDrive セッション中はそのデータをメモリ内に保持します。インメモリ キャッシュが大きくなり過ぎないように、このキャッシュのサイズを制限するための仕組みも用意しています。

新しい SkyDrive アーキテクチャで導入されたもう 1 つの概念が、事前キャッシュという考え方です。新しい SkyDrive フォト ビューアーでフォト アルバムを表示する場合、SkyDrive によって写真のダウンロードが開始され、その写真にアクセスしたときには、既にローカル コンピューター上に保存されています。ただし、表示しない写真も事前キャッシュすると、一定のネットワーク呼び出しとサーバー サイクルが無駄になるので、事前キャッシュでは微妙なバランスを維持する必要があります。ファイル リスト ビューでは、別のタイプの事前キャッシュも行っています。このビューでは、スクロールがスムーズになるように、現在のビューよりも余分にアイテムをフェッチしています。

今後も HTML 5 の機能をさらに活用

SkyDrive の最新リリースでは、多くの新しい Web 標準を採用しました。サーバーと通信するときには、JSON を使用してユーザー データを表現します。CSS アニメーション、リフロー アニメーション、およびその他の機能には、HTML5 を使用しています。キャッシュのサポートのさまざまな部分にはローカル ストレージを使用しています。また、ここで説明した機能ができるだけ多くの最新のブラウザーで動作するように、使用する HTML の標準準拠の作業を進めてきました。

今後も、HTML5 の機能をどんどん活用していく予定です。リッチ アップロード コントロールには Silverlight を使用していますが、これは、アップロードの前に写真を小さなサイズに変更できるためです。またこのリリースから、すべての JavaScript が JQuery 上で構築されています。これは、JQuery によって開発者の生産性が向上することがわかったためです。SkyDrive の PC ビューとモバイル ビューではすべてのコードが再利用されており、モバイル エクスペリエンスもこれまで以上に高速化されています。

他の SkyDrive エクスペリエンスについても、新しい高速なアーキテクチャへの展開を進めています。近い将来、より多くの項目が “インライン化” され、ページ全体の読み込みを行わずに、クライアントから動的に駆動できるようになる予定です。削除や移動などの操作も、ページ読み込みではなく非同期操作になるように移行作業を進めています。

SkyDrive エクスペリエンスの快適化には速度が重要であることは明白であるため、今後も引き続き SkyDrive のパフォーマンス向上を重視して取り組んでいきます。

高速化された新しい SkyDrive に対するご意見、ご感想をお寄せください。

Steven Bailey
Development Manager, Windows Live

,

%d人のブロガーが「いいね」をつけました。