Next.js がルート プリフェッチを使用してナビゲーションを高速化する仕組みと、それをカスタマイズする方法。
学習内容
この記事では、Next.js でのルーティングの仕組み、速度を重視した最適化方法、ニーズに合わせてカスタマイズする方法について説明します。
<Link> コンポーネント
Next.js では、ルーティングを手動で設定する必要はありません。Next.js はファイル システムベースのルーティングを使用します。これにより、./pages/ ディレクトリ内にファイルとフォルダを作成できます。
別のページにリンクするには、従来の <a> 要素を使用する場合と同様に、<Link> コンポーネントを使用します。
<Link href="/margherita">
<a>Margherita</a>
</Link>
ナビゲーションに <Link> コンポーネントを使用すると、Next.js がさらに多くの処理を行います。通常、ページはリンクをクリックしたときにダウンロードされますが、Next.js はページのレンダリングに必要な JavaScript を自動的にプリフェッチします。
リンクがいくつかあるページを読み込むと、リンク先のコンポーネントがすでにフェッチされている可能性があります。これにより、新しいページへのナビゲーションが高速化され、アプリケーションの応答性が向上します。
次のサンプルアプリでは、index.js ページが <Link> を使用して margherita.js にリンクしています。
Chrome DevTools を使用して、margherita.js がプリフェッチされていることを確認します。サイトをプレビューするには、[アプリを表示] を押してから、[全画面表示] を押します。
- Ctrl+Shift+J(Mac の場合は Command+Option+J)キーを押して、デベロッパー ツールを開きます。
[ネットワーク] タブをクリックします。
[キャッシュを無効にする] チェックボックスをオンにします。
ページを再読み込みする。
index.js を読み込むと、[ネットワーク] タブに margherita.js もダウンロードされていることが示されます。
![margherita.js がハイライト表示された DevTools の [ネットワーク] タブ。](https://web.dev/static/articles/route-prefetching-in-nextjs/image/devtools-network-tab-mar-ff03141455652.png?authuser=0&hl=ja)
自動プリフェッチの仕組み
Next.js は、ビューポートに表示されるリンクのみをプリフェッチし、Intersection Observer API を使用して検出します。また、ネットワーク接続が遅い場合や、ユーザーが Save-Data をオンにしている場合も、プリフェッチが無効になります。これらのチェックに基づいて、Next.js は <link
rel="preload"> タグを動的に挿入して、後続のナビゲーション用のコンポーネントをダウンロードします。
Next.js は JavaScript を取得するだけで、実行しません。これにより、リンクにアクセスするまで、プリフェッチされたページがリクエストする追加のコンテンツはダウンロードされません。
不要なプリフェッチを回避する
不要なコンテンツのダウンロードを回避するには、<Link> の prefetch プロパティを false に設定して、アクセス頻度の低いページのプリフェッチを無効にします。
<Link href="/pineapple-pizza" prefetch={false}>
<a>Pineapple pizza</a>
</Link>
この 2 番目のサンプルアプリの index.js ページには、prefetch が false に設定された <Link> から pineapple-pizza.js へのリンクがあります。
ネットワーク アクティビティを調べるには、最初の例の手順に沿って操作します。index.js を読み込むと、DevTools の [Network] タブに、margherita.js はダウンロードされているが pineapple-pizza.js はダウンロードされていないことが示されます。
![margherita.js がハイライト表示された DevTools の [ネットワーク] タブ。](https://web.dev/static/articles/route-prefetching-in-nextjs/image/devtools-network-tab-mar-6cc6381202dec.png?authuser=0&hl=ja)
カスタム ルーティングによるプリフェッチ
<Link> コンポーネントはほとんどのユースケースに適していますが、独自のコンポーネントを構築してルーティングを行うこともできます。Next.js では、next/router で利用可能なルーター API を使用して、これを簡単に行うことができます。新しいルートに移動する前に何か(フォームの送信など)を行う場合は、カスタム ルーティング コードで定義できます。
ルーティングにカスタム コンポーネントを使用する場合は、プリフェッチも追加できます。ルーティング コードにプリフェッチを実装するには、useRouter の prefetch メソッドを使用します。
このサンプルアプリの components/MyLink.js を見てみましょう。
プリフェッチは useEffect フック内で行われます。<MyLink> の prefetch プロパティが true に設定されている場合、その <MyLink> がレンダリングされると、href プロパティで指定されたルートがプリフェッチされます。
useEffect(() => {
if (prefetch) router.prefetch(href)
});
リンクをクリックすると、handleClick でルーティングが行われます。メッセージがコンソールにログに記録され、push メソッドは href で指定された新しいルートに移動します。
const handleClick = e => {
e.preventDefault();
console.log("Having fun with Next.js.");
router.push(href);
};
このサンプルアプリの index.js ページには、margherita.js と pineapple-pizza.js への <MyLink> があります。prefetch プロパティは、/margherita では true に、/pineapple-pizza では false に設定されています。
<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza" title="Pineapple pizza" prefetch={false} />
index.js を読み込むと、[ネットワーク] タブに、margherita.js がダウンロードされ、pineapple-pizza.js がダウンロードされていないことが示されます。
![margherita.js がハイライト表示された DevTools の [ネットワーク] タブ。](https://web.dev/static/articles/route-prefetching-in-nextjs/image/devtools-network-tab-mar-0199e278ff707.png?authuser=0&hl=ja)
どちらかのリンクをクリックすると、コンソールに「Having fun with Next.js」がログに記録され、新しいルートに移動します。

まとめ
<Link> を使用すると、リンクされたページのレンダリングに必要な JavaScript が Next.js によって自動的にプリフェッチされるため、新しいページへの移動が速くなります。カスタム ルーティングを使用している場合は、Next.js ルーター API を使用してプリフェッチを実装できます。アクセス頻度の低いページのプリフェッチを無効にして、コンテンツを不必要にダウンロードしないようにします。