クイックリンクで React のナビゲーションを高速化

React のシングルページ アプリケーションのクイックリンクを使用して、ビューポート内のリンクを自動的にプリフェッチします。

プリフェッチは、次のページのリソースを事前にダウンロードすることで移動をスピードアップする手法です。Quicklink は、ビューに表示されるリンクを自動的にプリフェッチすることで、この手法を大規模に実装できるライブラリです。

マルチページ アプリでは、ビューポート内のリンクについて、ライブラリがドキュメント(/article.html など)をプリフェッチします。これにより、ユーザーがこれらのリンクをクリックすると、HTTP キャッシュから取得できるようになります。

シングルページ アプリでは、ルートベースのコード分割と呼ばれる手法が一般的に使用されます。これにより、ユーザーがそのルートに移動したときにのみ、サイトで特定のルートのコードを読み込むことができます。このようなファイル(JS、CSS)は、一般に「チャンク」と呼ばれます。

とは言え、こうしたサイトでは、ドキュメントをプリフェッチするのではなく、ページが必要とする前にチャンクをプリフェッチすると、最大のパフォーマンス向上が実現します。

これを達成するにはいくつかの課題があります。

  • 特定のルート(/article など)にたどり着く前にどのチャンク(article.chunk.js など)が関連付けられているかを判断するのは簡単なことではありません。
  • 最新のモジュール バンドラは通常、バージョニングのために長期のハッシュを使用する(例: article.chunk.46e51.js)ため、これらのチャンクの最終ページ URL 名は予測できません。

このガイドでは、Quicklink がこれらの課題をどのように解決し、React のシングルページ アプリで大規模にプリフェッチを実現できるかについて説明します。

で確認できます。

各ルートに関連付けられたチャンクを特定する

quicklink のコア コンポーネントの 1 つが webpack-route-manifest です。これは、ルートとチャンクからなる JSON 辞書を生成できる webpack プラグインです。 これにより、ライブラリはアプリの各ルートでどのファイルが必要になるかを把握し、ルートがビューに入ったときにそれらをプリフェッチできます。

プロジェクトにプラグインを統合すると、各ルートを対応するチャンクに関連付ける JSON マニフェスト ファイルが生成されます。

{
  '/about': [
    {
      type: 'style',
      href: '/static/css/about.f6fd7d80.chunk.css',
    },
    {
      type: 'script',
      href: '/static/js/about.1cdfef3b.chunk.js',
    },
  ],
  '/blog': [
    {
      type: 'style',
      href: '/static/css/blog.85e80e75.chunk.css',
    },
    {
      type: 'script',
      href: '/static/js/blog.35421503.chunk.js',
    },
  ],
}

このマニフェスト ファイルは、次の 2 つの方法でリクエストできます。

  • URL を使用。例:https://site_url/rmanifest.json
  • window.__rmanifest の window オブジェクトを使用します。

ビューポート内のルートのチャンクをプリフェッチする

マニフェスト ファイルが使用可能になったら、次に npm install quicklink を実行して Quicklink をインストールします。

次に、高次コンポーネント(HOC)withQuicklink() を使用して、リンクがビューに入ったときに特定のルートをプリフェッチする必要があることを示すことができます。

次のコードは、4 つのリンクを含むトップメニューをレンダリングする React アプリの App コンポーネントに含まれています。

const App = () => (
  <div className={style.app}>
    <Hero />
    <main className={style.wrapper}>
      <Suspense fallback={<div>Loading</div>}>
        <Route path="/" exact component={Home} />
        <Route path="/blog" exact component={Blog} />
        <Route path="/blog/:title" component={Article} />
        <Route path="/about" exact component={About} />
      </Suspense>
    </main>
    <Footer />
  </div>
);

これらのルートがビューに入ったときにプリフェッチされるように Quicklink に指示するには:

  1. コンポーネントの先頭で quicklink HOC をインポートします。
  2. 各ルートを withQuicklink() HOC でラップし、ページ コンポーネントとオプション パラメータをそのルートに渡します。
const options = {
  origins: [],
};
const App = () => (
  <div className={style.app}>
    <Hero />
    <main className={style.wrapper}>
      <Suspense fallback={<div>Loading…</div>}>
        <Route path="/" exact component={withQuicklink(Home, options)} />
        <Route path="/blog" exact component={withQuicklink(Blog, options)} />
        <Route
          path="/blog/:title"
          component={withQuicklink(Article, options)}
        />
        <Route path="/about" exact component={withQuicklink(About, options)} />
      </Suspense>
    </main>
    <Footer />
  </div>
);

withQuicklink() HOC は、ルートのパスをキーとして使用し、関連するチャンクを rmanifest.json から取得します。 リンクがビューに入ると、ライブラリは内部で各チャンクの <link rel="prefetch"> タグをページに挿入し、プリフェッチできるようにします。 プリフェッチされたリソースは、ブラウザによって最も低い優先度でリクエストされ、HTTP キャッシュに 5 分間保持されます。その後、リソースの cache-control ルールが適用されます。 その結果、ユーザーがリンクをクリックして特定のルートに移動したときにチャンクがキャッシュから取得され、そのルートのレンダリングにかかる時間が大幅に短縮されます。

まとめ

プリフェッチによって、今後のナビゲーションの読み込み時間を大幅に短縮できます。React のシングルページ アプリでは、ユーザーが到達する前に各経路に関連付けられたチャンクを読み込むことで、これを実現できます。 React SPA 向けの Quicklink のソリューションは、webpack-route-manifest を使用してルートとチャンクのマップを作成し、リンクがビューに入ったときにどのファイルをプリフェッチするかを決定します。 このテクニックをサイト全体に導入すると、ナビゲーションを大幅に改善して、すぐに表示されるようにすることができます。