予測プリフェッチでウェブ ナビゲーションを高速化

予測プリフェッチと、Guess.js による実装方法について説明します。

Google I/O 2019 で開催された「予測プリフェッチによるウェブ ナビゲーションの高速化」のセッションでは、コードの分割によるウェブアプリの最適化と、後続のページ ナビゲーションのパフォーマンスへの影響について最初にお話ししました。第 2 部では、Guess.js を使用して予測プリフェッチをセットアップし、ナビゲーション速度を改善する方法について説明しました。

コード分割によるウェブアプリの高速化

ウェブアプリは処理が遅く、JavaScript は最も高価なリソースの 1 つです。ウェブアプリの読み込みが遅いと、ユーザーに不満を感じ、コンバージョンが減少する可能性があります。

動作が遅いウェブアプリにはストレスがかかります。

遅延読み込みは、有線で転送する JavaScript のバイト数を減らすための効率的な手法です。JavaScript を遅延読み込みするには、次のようないくつかの手法を使用できます。

  • コンポーネント レベルでのコード分割
  • ルートレベルでのコード分割

コンポーネント レベルでコード分割を行うと、個々のコンポーネントを別々の JavaScript チャンクに移動できます。特定のイベントでは、関連するスクリプトを読み込んでコンポーネントをレンダリングできます。

ただし、ルートレベルでコード分割を行う場合、ルート全体を独立したチャンクに移動します。あるルートから別のルートにユーザーが移るときに、関連する JavaScript をダウンロードして、リクエストされたページをブートストラップする必要があります。これらの操作は、特に低速なネットワークでは、大幅な遅延につながる可能性があります。

JavaScript のプリフェッチ

プリフェッチにより、ユーザーがすぐに必要になりそうなリソースをブラウザでダウンロードしてキャッシュに保存できます。通常は <link rel="prefetch"> を使用しますが、よく見られる注意点が 2 つあります。

  • 過剰な数のリソースのプリフェッチ(オーバーフェッチ)は大量のデータを消費します。
  • ユーザーが必要とするリソースの中には、プリフェッチされないものもあります。

予測プリフェッチは、ユーザーのナビゲーション パターンのレポートを使用してプリフェッチするアセットを特定することで、これらの問題を解決します。

プリフェッチの例

Guess.js を使用した予測プリフェッチ

Guess.js は、予測プリフェッチ機能を提供する JavaScript ライブラリです。Guess.js は、Google アナリティクスや他のアナリティクス プロバイダのレポートを使用して、ユーザーが必要としそうなものだけをスマートにプリフェッチできる予測モデルを構築します。

Guess.js は、AngularNext.jsNuxt.jsGatsby と統合できます。これをアプリケーションで使用するには、webpack の構成に次の行を追加して、Google アナリティクスのビュー ID を指定します。

const { GuessPlugin } = require('guess-webpack');

// ...
plugins: [
   // ...
   new GuessPlugin({ GA: 'XXXXXX' })
]
// ...

Google アナリティクスを使用していない場合は、reportProvider を指定して、お気に入りのサービスからデータをダウンロードできます。

フレームワークとの統合

Guess.js をお気に入りのフレームワークと統合する方法については、以下のリソースをご覧ください。

Angular との統合に関する簡単なチュートリアルについては、こちらの動画をご覧ください。

Guess.js の仕組み

Guess.js による予測プリフェッチの実装方法を以下に示します。

  1. まず、任意の分析プロバイダからユーザーのナビゲーション パターンのデータを抽出します。
  2. 次に、レポートの URL を、webpack によって生成された JavaScript チャンクにマッピングします。
  3. 抽出されたデータに基づいて、ユーザーが任意のページからアクセスする可能性の高いページについて、単純な予測モデルを作成します。
  4. JavaScript の各チャンクのモデルを呼び出し、次に必要になる可能性が高い他のチャンクを予測します。
  5. 各チャンクにプリフェッチ命令を追加します。

Guess.js が完了すると、各チャンクに次のようなプリフェッチ命令が含まれます。

__GUESS__.p(
  ['a.js', 0.2],
  ['b.js', 0.8]
)

この Guess.js で生成されたコードは、確率が 0.2 のチャンク a.js と確率が 0.8 のチャンク b.js をプリフェッチするようブラウザに指示します。

ブラウザでコードが実行されると、Guess.js によってユーザーの接続速度が確認されます。十分な場合、Guess.js はページのヘッダーに 2 つの <link rel="prefetch"> タグ(チャンクごとに 1 つ)を挿入します。ユーザーが高速ネットワークに接続している場合、Guess.js は両方のチャンクをプリフェッチします。ユーザーのネットワーク接続が不安定な場合、Guess.js はチャンク b.js のみをプリフェッチします。これは、必要になる可能性が高いためです。

さらに詳しく

Guess.js について詳しくは、以下のリソースをご覧ください。