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

特定のハードウェアとネットワークの制約に合わせてサイトを最適化し、すべてのユーザーに最適なエクスペリエンスを提供する方法をご確認ください。

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

Chrome Dev Summit での講演で、Google のアディー オスマニ氏と Facebook のネイト シュロス氏は、この問題の解決策として、さまざまなユーザーの制約に適したページを配信するためのパターンについて説明しています。これはアダプティブ読み込みと呼ばれます。

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

アダプティブ読み込みでは、ネットワークとハードウェアの制約に基づいて、ユーザーごとに異なるエクスペリエンスを提供します。具体的には、次のようなエクスペリエンスです。

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

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

特定のハードウェアとネットワークの制約に合わせて最適化することで、すべてのユーザーがデバイスで最適なエクスペリエンスを得ることができます。ユーザーの制約に合わせてエクスペリエンスを調整する方法には、次のものがあります。

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

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

  • ローエンド デバイスでの計算コストの高いオペレーションを避ける。

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

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

ブラウザのサポートと適応型読み込みの実装方法

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

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

対応ブラウザ

  • Chrome: 63。
  • Edge: 79.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

navigator.hardwareConcurrency プロパティは CPU コア数です。これは、コストの高い JavaScript の実行を制限し、デバイスが CPU 使用率の高いロジックを適切に処理できない場合にそのロジックを削減するために使用されます。

対応ブラウザ

  • Chrome: 37。
  • Edge: 15。
  • Firefox: 48.
  • Safari: サポートされていません。

ソース

NetworkInformation.effectiveType

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

対応ブラウザ

  • Chrome: 61。
  • Edge: 79.
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

NetworkInformation.saveData

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

対応ブラウザ

  • Chrome: 49.
  • Edge: ≤79。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

ユーザーに提供するコンテンツを決定する場所は、クライアントとサーバーです。クライアントには、上記の JavaScript API があります。サーバーでクライアント ヒントを使用して、ユーザーのデバイスの機能と接続されているネットワークに関する分析情報を取得できます。

React のアダプティブ読み込み

React Adaptive Loading Hooks &Utilities は React エコシステム用のスイートで、サイトをローエンド デバイスに簡単に適応させることができます。次の内容が含まれます。

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

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

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

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

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

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

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

このセクションでは、適応型読み込みの使用方法のデモと、Facebook、eBay、Tinder などのサイトの実際の例について説明します。

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

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

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

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

低価格デバイスと高価格デバイスの商品ページ用に配信されるモジュールの図: どちらのバージョンにも

Tinder は、ウェブLite アプリでさまざまな適応型読み込みパターンを使用して、すべてのユーザーが高速なエクスペリエンスを維持できるようにしています。ユーザーが低速なネットワークを使用している場合やデータセーバーを有効にしている場合、動画の自動再生は無効になり、ルートのプリフェッチが制限され、カルーセル内の次の画像の読み込みは、ユーザーがスワイプするたびに 1 枚ずつ読み込まれるようになります。これらの最適化を実装した後、インドネシアなどの国で平均スワイプ数が大幅に改善されました。

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

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

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

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

動画の 24 分あたりで、Facebook がデバイスのグループ化に取り組む方法と、アニメーションと JavaScript の読み込みに適応型読み込みを使用する方法について、Nate が説明しています。

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

アダプティブ読み込みは、包括性を念頭に置いてサイトを設計することです。すべてのユーザーに適したコア エクスペリエンスを構築し、ユーザーが十分なメモリ、CPU、高速ネットワークを備えている場合は、さらに優れたエクスペリエンスを実現する機能を切り替えたり、重ねたりします。アダプティブ ローディングの詳細については、利用可能なデモと Chrome Dev Summit のトークをご覧ください。