Отложенная загрузка (lazy loading) данных в TanStack Router позволяет оптимизировать производительность приложения, загружая только те данные, которые необходимы для рендера текущего маршрута, и откладывая загрузку менее критичных ресурсов до момента, когда они действительно понадобятся. Такой подход особенно эффективен для крупных приложений с множеством маршрутов и компонент, которые требуют обращения к серверу или выполнению сложных вычислений.
Ключевые преимущества включают сокращение времени первичной загрузки, снижение нагрузки на сеть и улучшение отзывчивости интерфейса.
В TanStack Router маршруты описываются объектами, где ключевым
элементом является loader. Для реализации отложенной
загрузки некритичных данных используется возможность возвращать из
loader промис, который будет выполняться асинхронно.
import { createRouter, RouterProvider } from '@tanstack/router';
const router = createRouter({
routes: [
{
path: '/',
element: <HomePage />,
loader: async () => {
const criticalData = await fetch('/api/critical').then(res => res.json());
return { criticalData };
},
children: [
{
path: 'extra',
element: <ExtraData />,
loader: async () => {
const extraData = await fetch('/api/extra').then(res => res.json());
return { extraData };
},
},
],
},
],
});
В данном примере данные, необходимые для первичной отрисовки главной
страницы, загружаются сразу. Некритичные данные, например, для
компонента ExtraData, загружаются только при переходе на
соответствующий маршрут.
defer для отложенной загрузкиTanStack Router предоставляет функцию defer, которая
позволяет разделять загрузку критичных и некритичных данных внутри
одного маршрута. Критичные данные передаются сразу, а некритичные
оборачиваются в отложенный промис.
import { defer } from '@tanstack/router';
const router = createRouter({
routes: [
{
path: '/profile',
element: <ProfilePage />,
loader: () => {
const userDataPromise = fetch('/api/user').then(res => res.json());
const recommendationsPromise = fetch('/api/recommendations').then(res => res.json());
return defer({
userData: userDataPromise, // критичные данные
recommendations: recommendationsPromise, // некритичные, загрузка будет deferred
});
},
},
],
});
defer возвращает объект, где свойства могут быть как
синхронными, так и промисами. TanStack Router обеспечивает корректное
управление состоянием загрузки, позволяя отображать скелетон или
индикатор загрузки для некритичных данных, пока они подтягиваются.
Для работы с отложенными данными в компонентах используется хук
useLoaderData совместно с функцией
useAsyncData для получения состояния загрузки промисов. Это
позволяет отделить рендеринг критичных данных от некритичных.
import { useLoaderData, useAsyncData } from '@tanstack/router';
function ProfilePage() {
const { userData, recommendations } = useLoaderData();
const { data: recData, isLoading } = useAsyncData(recommendations);
return (
<div>
<h1>{userData.name}</h1>
<section>
<h2>Рекомендации</h2>
{isLoading ? (
<p>Загрузка рекомендаций...</p>
) : (
<ul>
{recData.map(item => (
<li key={item.id}>{item.title}</li>
))}
</ul>
)}
</section>
</div>
);
}
Такой подход позволяет отображать критичные данные немедленно, а некритичные — по мере их загрузки, не блокируя интерфейс.
TanStack Router поддерживает интеграцию с React Suspense, что
обеспечивает декларативное управление состояниями загрузки. Отложенные
данные можно оборачивать в <Suspense> для показа
placeholder-контента.
import { Suspense } from 'react';
import { useLoaderData, useAsyncData } from '@tanstack/router';
function ProfilePage() {
const { userData, recommendations } = useLoaderData();
return (
<div>
<h1>{userData.name}</h1>
<Suspense fallback={<p>Загрузка рекомендаций...</p>}>
<Recommendations recommendationsPromise={recommendations} />
</Suspense>
</div>
);
}
function Recommendations({ recommendationsPromise }) {
const { data } = useAsyncData(recommendationsPromise);
return (
<ul>
{data.map(item => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
}
Использование Suspense позволяет централизованно
управлять состоянием загрузки, упрощая рендеринг отложенных данных и
минимизируя boilerplate код.
React.lazy для отложенной загрузки тяжелых компонентов
вместе с отложенными данными.Для некритичных данных рекомендуется использовать отдельные API-запросы, которые не блокируют первичный рендер. Также полезно применять стратегию prefetching, когда данные загружаются заранее при наведении на ссылку или при прогнозируемой навигации, что уменьшает задержку при переходе на маршрут с отложенными данными.
Отложенная загрузка некритичных данных в TanStack Router позволяет
создавать быстрые и отзывчивые интерфейсы. Комбинация
defer, useAsyncData и React Suspense дает
полный контроль над асинхронными потоками данных, позволяя отображать
критичный контент мгновенно, а менее важный — постепенно, без блокировки
интерфейса. Такой подход особенно полезен в крупных SPA и PWA, где
оптимизация загрузки напрямую влияет на пользовательский опыт и
показатели производительности.