Стратегии загрузки

TanStack Router предоставляет гибкие механизмы управления загрузкой данных и компонентов, обеспечивая высокую производительность и оптимальное взаимодействие с пользователем. Стратегии загрузки определяют, когда и как данные загружаются, а также в каком порядке рендерятся компоненты. Рассмотрим основные подходы и их применение.


1. Ленивая загрузка компонентов (Lazy Loading)

TanStack Router поддерживает ленивую загрузку компонентов с помощью динамического импорта. Это позволяет уменьшить первоначальный размер бандла и ускорить время первой отрисовки страницы.

import { createRouter, Route } from '@tanstack/router'

const Home = React.lazy(() => import('./pages/Home'))
const About = React.lazy(() => import('./pages/About'))

const router = createRouter({
  routeTree: [
    Route({ path: '/', component: Home }),
    Route({ path: '/about', component: About }),
  ],
})

Ключевые моменты:

  • Компоненты загружаются только при переходе на соответствующий маршрут.
  • Использование React.Suspense позволяет показывать индикатор загрузки.
  • Снижается первоначальная нагрузка на сеть и память, улучшая UX на больших проектах.
<React.Suspense fallback={<div>Загрузка...</div>}>
  <RouterProvider router={router} />
</React.Suspense>

2. Предзагрузка данных (Prefetching)

TanStack Router поддерживает стратегию предзагрузки данных для маршрутов, к которым пользователь вероятно перейдет. Это позволяет минимизировать задержки при навигации.

const productRoute = Route({
  path: '/product/:id',
  loader: async ({ params }) => {
    const response = await fetch(`/api/products/${params.id}`)
    return response.json()
  },
})

Методы предзагрузки:

  • On Hover Prefetch: данные загружаются при наведении курсора на ссылку.
  • On Intent Prefetch: запуск загрузки при предполагаемом намерении пользователя (например, первый скролл к ссылке).
  • On Visibility Prefetch: загрузка начинается, когда элемент становится видимым в viewport.
<Link
  to="/product/123"
  onMouseEn ter={() => router.prefetchRoute('/product/123')}
>
  Подробнее
</Link>

3. Постепенная загрузка данных (Progressive Loading)

Для страниц с большим объемом данных TanStack Router позволяет реализовать постепенную загрузку. Вместо ожидания полного ответа API, данные могут рендериться частями.

const commentsRoute = Route({
  path: '/post/:id/comments',
  loader: async ({ params, signal }) => {
    const stream = await fetch(`/api/posts/${params.id}/comments/stream`, { signal })
    return stream.body
  },
})

Особенности:

  • Используется AbortController для отмены загрузки при уходе со страницы.
  • Можно комбинировать с Suspense и React.lazy для постепенного отображения блоков интерфейса.

4. Загрузка с кэшированием и мемоизацией

TanStack Router интегрируется с TanStack Query для управления состоянием данных. Это позволяет использовать кэширование и мемоизацию запросов, чтобы повторные переходы к маршруту выполнялись мгновенно.

import { useQuery } from '@tanstack/react-query'

const loader = async ({ params }) => {
  return useQuery(['product', params.id], () =>
    fetch(`/api/products/${params.id}`).then(res => res.json())
  )
}

Преимущества:

  • Сокращение количества сетевых запросов.
  • Быстрая реакция интерфейса на повторные переходы.
  • Настраиваемое время жизни кэша (staleTime), позволяющее контролировать актуальность данных.

5. Комбинированные стратегии (Hybrid Loading)

Для сложных приложений часто применяется сочетание разных стратегий:

  • Ленивая загрузка компонентов + Предзагрузка данных на пользовательский интент.
  • Прогрессивная загрузка для больших коллекций + Кэширование через TanStack Query.
  • Приоритетная загрузка критичных данных и отложенная загрузка второстепенных ресурсов.
const dashboardRoute = Route({
  path: '/dashboard',
  component: React.lazy(() => import('./pages/Dashboard')),
  loader: async () => {
    const criticalData = await fetch('/api/critical').then(res => res.json())
    return { criticalData }
  },
})

Рекомендации по использованию гибридных стратегий:

  • Сначала загружаются минимально необходимые данные для первой отрисовки.
  • Второстепенные данные подгружаются асинхронно.
  • Предзагрузка для соседних маршрутов повышает отзывчивость приложения.

6. Управление отменой загрузки (Abort Handling)

TanStack Router позволяет безопасно отменять загрузку данных при смене маршрута, что предотвращает устаревшие рендеры и утечки памяти.

const userRoute = Route({
  path: '/user/:id',
  loader: async ({ params, signal }) => {
    const response = await fetch(`/api/users/${params.id}`, { signal })
    return response.json()
  },
})

Принцип работы:

  • Передается signal из AbortController.
  • Любая асинхронная операция может быть прервана при навигации.
  • Уменьшается нагрузка на сеть и предотвращаются гонки данных.

7. Стратегии оптимизации производительности

Для улучшения скорости загрузки и рендеринга компонентов используются следующие подходы:

  • Split Routes: деление маршрутов на отдельные модули для уменьшения размера бандла.
  • Data Layer Separation: разделение загрузки критичных и некритичных данных.
  • Cache & Prefetch: совместное использование кэша и предзагрузки для часто посещаемых страниц.
  • Concurrency Control: ограничение количества параллельных загрузок для уменьшения нагрузки на сервер и клиент.

Эти стратегии позволяют строить эффективные, отзывчивые приложения, минимизировать время ожидания пользователя и контролировать загрузку ресурсов на каждом маршруте TanStack Router.