遅延ルート発見(別名「霧の戦争」)

Remix は、v2.10.0future.unstable_lazyRouteDiscovery Future Flag (後に v2.13.0future.v3_lazyRouteDiscovery として安定化)の背後にある遅延ルート発見(別名「霧の戦争」)RFC のサポートを導入しました。これは、この動作をオプトインできるようになり、Remix の次のメジャーバージョン(別名 React Router v7)12 ではデフォルトになります。この機能の詳細については、ブログ投稿 をご覧ください。

現在の動作

現在、Remix は最初のロード(例:/assets/manifest-[hash].js)時に完全なルートマニフェストを JS ファイルにロードします。マニフェストには、ルートモジュールの実装ではなく、それらの URL パスとメタ情報(ルート JS/CSS インポート、サーバーに loader/action があるかどうかなど)が含まれています。この完全なマニフェストを事前に持つことで、Remix はリンククリック時に同期的なクライアント側ルートマッチングを実行し、ルートモジュールとデータのロードをすぐに開始できます。中小規模のアプリケーションでは、完全なマニフェストを事前にロードしても通常は問題ありません。これは高度にキャッシュ可能であり、非常に効率的に圧縮されるためです。ただし、大規模なアプリケーションでは、このマニフェストが大きくなりすぎて、パフォーマンス指標に影響を与えることがわかりました。

新しい動作

「霧の戦争」を有効にすると、Remix は最初のロード時に完全なルートマニフェストを送信しなくなります。代わりに、SSR レンダリングには、最初のマニフェストに SSR ルートのみが含まれ、ユーザーがアプリケーション内を移動するにつれて追加のルートがロードされます。時間の経過とともに、マニフェストはユーザーが移動したアプリの部分を含むように成長します。

これは、アプリケーションの URL をエンドユーザーから「隠す」ための方法ではないことに注意してください。最初にすべてをマニフェストに配送するわけではありませんが、ユーザーがアプリケーション内を移動する際に新しいルートを取得するために使用されるマニフェストエンドポイントは、すべての定義済みアプリケーションルートを公開する機能を依然として持っています。ただし、少しわかりにくくなっています。

アグレッシブなルート発見

常に、このような遅延ルート発見にはトレードオフがあります。初期のアプリケーションロード時間は改善されますが、Remix はリンククリック時に同期的なルートマッチングを実行できなくなり、ウォーターフォールが発生する可能性があります。

現在のアーキテクチャ(<Link prefetch> を使用しない)では、リンクをクリックすると、次のような処理が行われます。

click /a
        |-- ルートモジュールをロードする -->
        |-- ルートデータをロードする -->
                                 | /a をレンダリングする

「霧の戦争」アーキテクチャでは、リンクをクリックすると、ウォーターフォールが発生する可能性があります。

click /a
        |-- ルートを検出する -->
                              |-- ルートモジュールをロードする -->
                              |-- ルートデータをロードする -->
                                                       | /a をレンダリングする

ご存じのとおり、Remix はウォーターフォールを嫌います。「霧の戦争」機能では、ほとんどの場合、ウォーターフォールを回避するための最適化が実装されています。デフォルトでは、ページにレンダリングされるすべての <Link> および <NavLink> コンポーネントはバッチ処理され、サーバーへのリクエストを介してアグレッシブに「検出」されます。このリクエストは、サーバー上の現在のすべてのリンクパスを照合し、必要なすべてのルートマニフェストエントリを送信します。ほとんどの場合、このリクエストはユーザーがリンクをクリックする前に完了するはずです(ユーザーは最初の数百ミリ秒間にリンクをクリックすることはないため)。マニフェストは、リンクがクリックされる前にパッチ処理されます。次に、リンクがクリックされると、Remix は「霧の戦争」の動作がなくても、同期的なクライアント側マッチングを実行できます。

このアグレッシブなルート発見をリンクごとにオプトアウトする場合は、discover="none" プロップを使用できます(デフォルト値は discover="render" です)。

注目すべき変更点

  • この機能が有効になっている場合、window.__remixManifest.routes のルートマニフェストには、最初の SSR で必要な最小限のルートのみが含まれ、ユーザーが移動するにつれてルートが動的に追加されます。
  • Remix ハンドラーには、マニフェストパッチを取得するための新しい内部 /__manifest エンドポイントが追加されました。
    • デプロイメントアーキテクチャが、/__manifest リクエストをすべて Remix ハンドラーにルーティングする必要があることを確認する必要があります。
    • CDN/Edge キャッシュレイヤーが設定されている場合は、/__manifest ルートは、キャッシュキーに含める必要がある可能性のある 2 つのクエリ文字列パラメーター(versionp)を受け入れます。
    • ⚠️ これは内部実装の詳細と見なされ、アプリケーションコードによってリクエストされることを意図していません。