Префетчинг маршрутов — это процесс загрузки данных или компонентов, связанных с определённым маршрутом, заранее, до того как пользователь фактически перейдёт на этот маршрут. Это повышает скорость отклика приложения и улучшает пользовательский опыт, особенно в сложных SPA с большим количеством асинхронных ресурсов.
React Router предоставляет возможность интеграции с префетчингом через два основных подхода:
React.lazy и
Suspenseloader)Пример ленивой загрузки компонента маршрута:
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: Загрузка... В данном примере компонент 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
Таким образом, при наведении одновременно загружается компонент и необходимые данные, минимизируя время ожидания пользователя.
Для больших приложений важно не загружать всё заранее. Можно внедрять условный префетчинг, основываясь на приоритетах страниц или поведении пользователя. Примеры подходов:
navigator.connection.effectiveType. в будущих версияхНекоторые библиотеки и экспериментальные подходы предлагают компонент
для декларативного задания маршрутов и
данных, которые необходимо предзагрузить. Основная идея — указать
ресурсы для префетчинга прямо в JSX, что делает код более читабельным и
поддерживаемым.