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

予測プリフェッチと Guess.js による実装について学びます。

Google I/O 2019 のセッション「予測型プリフェッチによるウェブ ナビゲーションの高速化」では、コード分割によるウェブアプリの最適化と、その後のページ ナビゲーションに及ぼすパフォーマンスへの影響について説明しました。講演の 2 番目のパートでは、Guess.js を使用して予測プリフェッチを設定し、ナビゲーション速度を改善する方法について説明しました。

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

ウェブアプリは遅く、JavaScript は最もコストの高いリソースの一つです。ウェブアプリの読み込みが遅いと、ユーザーの不満を招き、コンバージョンが減少する可能性があります。

ウェブアプリの動作が遅いとストレスになります。

遅延読み込みは、ワイヤーを介して転送する JavaScript のバイト数を削減するための効率的な手法です。JavaScript を遅延読み込みするには、次のような手法を使用できます。

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

コンポーネント レベルの Code Splitting を使用すると、個々のコンポーネントを個別の JavaScript チャンクに移動できます。特定のイベントで、関連するスクリプトを読み込み、コンポーネントをレンダリングできます。

一方、ルートレベルのコード分割では、ルート全体を独立したチャンクに移動します。ユーザーが 1 つのルートから別のルートに移動するときに、関連する 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 の詳細については、以下のリソースをご覧ください。