Префетчинг маршрутов

Префетчинг маршрутов — это процесс загрузки данных или компонентов, связанных с определённым маршрутом, заранее, до того как пользователь фактически перейдёт на этот маршрут. Это повышает скорость отклика приложения и улучшает пользовательский опыт, особенно в сложных SPA с большим количеством асинхронных ресурсов.

Механизм работы префетчинга

React Router предоставляет возможность интеграции с префетчингом через два основных подхода:

  1. Ленивая загрузка компонентов через React.lazy и Suspense
  2. Использование функций загрузки данных на уровне маршрута (loader)

Пример ленивой загрузки компонента маршрута:

import { lazy, Suspense } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const Dashboard = lazy(() => import("./pages/Dashboard"));
const Profile = lazy(() => import("./pages/Profile"));

const router = createBrowserRouter([
  {
    path: "/dashboard",
    element: Загрузка...
}> }, { path: "/profile", element: Загрузка...
}> } ]); export default function App() { return ; }

В данном примере компонент Dashboard и Profile загружаются только при переходе на соответствующий маршрут. Префетчинг позволяет инициировать загрузку заранее, например, при наведении курсора на ссылку.

Префетчинг компонентов при наведении

React Router не предоставляет встроенного хука для префетчинга на уровне компонента, но можно использовать метод import() для предзагрузки модуля вручную:

function preloadDashboard() {
  import("./pages/Dashboard");
}


  Перейти на Dashboard

В этом случае модуль Dashboard будет загружен в фоновом режиме при наведении мыши, и переход станет мгновенным.

Префетчинг данных маршрута через loader

В React Router v6.4+ появился концепт Data APIs, который позволяет задавать функцию loader для каждого маршрута. Она возвращает данные, необходимые для рендера компонента, и может работать с префетчингом.

import { createBrowserRouter } from "react-router-dom";

async function dashboardLoader() {
  const response = await fetch("/api/dashboard");
  if (!response.ok) throw new Error("Не удалось загрузить данные");
  return response.json();
}

const router = createBrowserRouter([
  {
    path: "/dashboard",
    element: ,
    loader: dashboardLoader
  }
]);

Для префетчинга данных можно инициировать вызов loader заранее:

import { useNavigate } from "react-router-dom";

function PreloadButton() {
  const navigate = useNavigate();

  async function handlePreload() {
    await dashboardLoader(); // загрузка данных заранее
    navigate("/dashboard");
  }

  return ;
}

Сочетание префетчинга компонентов и данных

Наиболее эффективный подход — комбинировать ленивую загрузку компонентов и предварительное получение данных:

function preloadDashboard() {
  import("./pages/Dashboard");
  dashboardLoader();
}


  Перейти на Dashboard

Таким образом, при наведении одновременно загружается компонент и необходимые данные, минимизируя время ожидания пользователя.

Отложенный префетчинг и оптимизация трафика

Для больших приложений важно не загружать всё заранее. Можно внедрять условный префетчинг, основываясь на приоритетах страниц или поведении пользователя. Примеры подходов:

Использование в будущих версиях

Некоторые библиотеки и экспериментальные подходы предлагают компонент для декларативного задания маршрутов и данных, которые необходимо предзагрузить. Основная идея — указать ресурсы для префетчинга прямо в JSX, что делает код более читабельным и поддерживаемым.