アダプティブ読み込み: 低速なデバイスでのウェブ パフォーマンスを向上

特定のハードウェアやネットワークの制約に合わせてサイトを最適化し、すべてのユーザーに可能な限り最適なエクスペリエンスを提供する方法を学びます。

デバイスの機能やネットワーク接続は大きく異なります。ハイエンド デバイスでユーザーを楽しませるサイトが、ローエンド デバイスで使用できない場合があります。高速ネットワークでスムーズに読み込まれるサイトは、低速のネットワークでは停止することがあります。ウェブサイトの速度が遅いことは、どのユーザーでも経験する可能性があります。そのため、「画一的なソリューション」の開発が必ずしもうまくいかないこともあります。

Google の Addy Osmani と Facebook の Nate Schloss が、Chrome Dev Summit の講演の中で、さまざまなユーザーの制約に応えるページ配信のパターンである、この問題の解決策を探っています。これをアダプティブ ローディングと呼びます。

アダプティブ読み込みとは

適応型読み込みでは、ネットワークとハードウェアの制約に基づいて、さまざまなユーザーにさまざまなエクスペリエンスを提供します。具体的には次のとおりです。

  • すべてのユーザーに高速なコア エクスペリエンス(ローエンド デバイスを含む)。

  • ユーザーのネットワークとハードウェアで処理できる場合は、ハイエンド専用の機能を段階的に追加する。

特定のハードウェアやネットワークの制約に合わせて最適化することで、すべてのユーザーに可能な限り最適なエクスペリエンスを提供できるようになります。ユーザーの制約に合わせてエクスペリエンスを調整すると、次のようなことが挙げられます。

  • 低速のネットワークでも低画質の画像や動画を配信する。

  • ローエンド デバイスでのアニメーションのフレームレートのスロットリング。

  • ローエンド デバイスで計算負荷の高いオペレーションを回避する。

  • 低速のデバイスでサードパーティ スクリプトをブロックする。

  • 高速 CPU でのみ、インタラクティビティのために重要ではない JavaScript を読み込みます。

ブラウザのサポートとアダプティブ ローディングの実装方法

アダプティブ読み込みに使用できるシグナルを以下に示します。各シグナルには、ブラウザ サポートも含まれます。

navigator.deviceMemory プロパティは、ローエンド デバイスのメモリ消費を削減するために使用されます。

対応ブラウザ

  • 63
  • 79
  • x
  • x

ソース

navigator.hardwareConcurrency プロパティは CPU コア数です。コストのかかる JavaScript の実行を制限し、デバイスで処理がうまくいかない場合に CPU 負荷の高いロジックを削減するために使用します。

対応ブラウザ

  • 37
  • 15
  • 48
  • x

ソース

NetworkInformation.effectiveType

navigator.connection.effectiveType プロパティは、データ転送を微調整して帯域幅の使用量を減らすために使用します。

対応ブラウザ

  • 61
  • 79
  • x
  • x

ソース

NetworkInformation.saveData

navigator.connection.saveData プロパティは、ユーザーのデータセーバー設定を利用するために使用されます。

対応ブラウザ

  • 49
  • 79 以下
  • x
  • x

ソース

ユーザーに提供する内容を決定する際には、クライアントとサーバーの 2 つの方法があります。クライアントには、前述の JavaScript API があります。サーバーでは、クライアント ヒントを使用して、ユーザーのデバイスの機能とユーザーが接続しているネットワークに関する分析情報を取得できます。

React でのアダプティブ ロード

React Adaptive Loading Hooks & Utilities は、サイトをローエンド デバイスに容易に適応させる React エコシステム用のスイートです。以下が含まれています。

  • ネットワーク ステータス(slow-2g2g3g4g)に基づいて適応するための useNetworkStatus() フック。

  • ユーザーのデータセーバー設定に基づいて適応するための useSaveData() フック。

  • ユーザーのデバイス上の論理 CPU プロセッサのコア数に基づいて適応するための useHardwareConcurrency() フック。

  • ユーザーのデバイスメモリ(RAM)に基づいて適応するための useMemoryStatus() フック。

各フックは、初期値を設定するためのオプションの引数を受け入れます。このオプションは、2 つのシナリオで役立ちます。1 つは、ユーザーのブラウザが該当する API をサポートしていない場合で、もう 1 つはサーバーサイド レンダリングで、Client Hints データを使用してサーバーに初期値を設定できる場合です。たとえば、useNetworkStatus() フックは、クライアント ヒントから渡された初期値をサーバーサイド レンダリングに使用できます。また、クライアントで実行すると、ネットワークの有効なタイプが変更されたときに自身を更新します。

React Adaptive Loading フックとユーティリティは、ウェブ プラットフォーム API(ネットワーク情報デバイスメモリハードウェアの同時実行)を使用して実装されます。同じ API を使用して、AngularVue などの他のフレームワークやライブラリに適応型読み込みのコンセプトを適用できます。

アダプティブ読み込みの動作

このセクションでは、アダプティブ ロードを使用するデモと、Facebook、eBay、Tinder などのサイトの実際の例を紹介します。

React Movie デモでは、ネットワーク ステータスに基づいてメディア配信を調整する方法を紹介しています。これは、ポスター、要約、キャストリストを表示する映画をブラウジングするためのアプリケーションです。ユーザーの有効な接続タイプに応じて、高速接続では高品質のポスターが、低速接続では低品質のポスターが配信されます。

Twitter には、データ使用量を減らすためのデータセーバー モードがあります。このモードでは、プレビュー画像は低解像度で読み込まれ、大きな画像はプレビューをタップした場合にのみ読み込まれます。このオプションを有効にすると、iOS と Android のユーザーは画像からのデータ使用量を 50%、ウェブのユーザーは 80% を節約できました。次の React のデモでは、Save Data フックを使用して Twitter のタイムラインを複製しています。DevTools の [ネットワーク] パネルを開いて、[データの保存] が無効になっている場合と有効になっている場合のスクロールによって転送されるデータ量の違いを確認します。

Twitter のタイムラインのスクロールとデータセーバーのオンとオフを比較したスクリーンキャスト。データセーバーがオンの場合、画像プレビューのみが読み込まれ、動画は自動再生されません。

eBay は、ユーザーのハードウェアやネットワーク条件が対応していない場合、ズームなどの機能を条件付きでオン / オフします。これは、適応性のあるコード分割とコード読み込みを通じて実現できます。つまり、よりインタラクティブなコンポーネントを条件付きで読み込むか、ハイエンド デバイスでは計算負荷の高いオペレーションを実行しますが、低速のデバイスではそのようなスクリプトをユーザーに送信しないようにできます。16 分の動画をご覧ください。デモ eBay の商品ページで、Addy が React.lazy() と Suspense を使用して実装したこのパターンを示しています。

ローエンドおよびハイエンド デバイスの製品ページ用に出荷されるモジュールの図(両方のバージョンを含む)

Tinder は、ウェブLite アプリでさまざまなアダプティブな読み込みパターンを使用して、すべてのユーザーのエクスペリエンスを高速に保っています。ユーザーが低速のネットワークを使用している場合やデータセーバーを有効にしている場合は、動画の自動再生を無効にし、ルートのプリフェッチを制限し、カルーセル内の次の画像の読み込みを、スワイプ時に一度に 1 枚の画像だけに制限します。こうした最適化を実装した結果、インドネシアなどの国での平均スワイプ数が大幅に改善されました。

Tinder チャットの 2 つのバージョン(動画の自動再生ありと再生ボタンのオーバーレイありの動画)のスクリーンショット。「データセーバーまたは 3G でカルーセル画像を制限する」と書かれた Tinder プロファイルのスクリーンショット。4G でのみビューポート内の動画をプリフェッチするためのコード スニペット。

Facebook でのアダプティブ読み込み

アダプティブ読み込みで生じる問題の一つは、利用可能なシグナルに基づいてデバイスをハイエンドのクラスとローエンドのクラスにグループ化することです。モバイル デバイスでは、ユーザー エージェント(UA)文字列がデバイス名を提供します。これにより、Facebook は一般公開されているデバイス特性に関するデータを使用して、モバイル デバイスをクラスにグループ化できます。ただし、デスクトップ デバイスの場合、UA から提供される関連情報はデバイスのオペレーティング システムのみです。

デスクトップ デバイスをグループ化する場合、Facebook は、オペレーティング システム、CPU コア数(navigator.hardwareConcurrency から取得)、RAM メモリ(navigator.deviceMemory)に関するデータをパフォーマンス モニタリングに記録します。さまざまな種類のハードウェアとパフォーマンスの関係を調べるため、デバイスを 5 つのカテゴリに分類しました。パフォーマンス モニタリングにハードウェア クラスが統合されているため、デバイスごとの Facebook プロダクトの使用状況をより詳細に把握でき、リグレッションをより簡単に特定できます。

24 分の動画をご覧ください。この動画では、Nate が Facebook でデバイス グルーピングのアプローチと、アダプティブ ロードを使用してアニメーションと JavaScript を読み込む方法について説明しています。

アダプティブ読み込みの詳細

アダプティブ読み込みは、インクルーシブなサイトを設計するための機能です。 誰にとっても使いやすいコア エクスペリエンスを構築し、ユーザーのメモリ、CPU、または高速ネットワークが十分にある場合に、さらに優れたものにする機能を切り替えたり、レイヤ化したりします。アダプティブ読み込みの詳細については、利用可能なデモと、Chrome Dev Summit の講演をご覧ください。