Prefetching маршрутов

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

Основные принципы работы prefetching

Prefetching в TanStack Router строится на следующих ключевых моментах:

  1. Загрузка данных заранее Любой маршрут может иметь асинхронный загрузчик данных (loader). Prefetching позволяет вызвать этот loader до того, как пользователь перейдет на маршрут. Это обеспечивает мгновенное отображение данных при навигации.

  2. Динамическая подгрузка компонентов Если маршрут использует ленивую загрузку компонента через React.lazy или аналог, prefetching инициирует загрузку бандла заранее, снижая perceptual delay при рендере.

  3. Кэширование результатов TanStack Router хранит результаты prefetching, чтобы при фактическом переходе не выполнять повторно те же асинхронные операции.

Настройка prefetching маршрута

Каждый маршрут может иметь опцию preload или prefetch. Основная схема:

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

const Home = lazy(() => import('./Home'));

const router = createRouter({
  routeTree: Route({
    path: '/',
    component: Home,
    loader: async () => {
      const response = await fetch('/api/home');
      return response.json();
    },
    prefetch: 'intent' // 'hover' | 'intent' | 'visible'
  }),
});

Опции prefetching:

  • hover — загрузка данных и компонентов при наведении курсора на ссылку маршрута.
  • intent — предзагрузка при явном намерении пользователя перейти (например, нажатие клавиши Tab для фокусировки).
  • visible — загрузка при появлении ссылки в зоне видимости (IntersectionObserver).

Использование useMatchRoute для управления prefetching

TanStack Router позволяет получать состояние маршрута через хук useMatchRoute. Это удобно для программного контроля prefetching:

import { useMatchRoute, useRouter } from '@tanstack/router';

function PrefetchLink({ to, children }) {
  const router = useRouter();
  const match = useMatchRoute(to);

  const handleMouseEnter = () => {
    if (match) {
      router.prefetchRoute(to);
    }
  };

  return (
    <a href={to} onMouseEn ter={handleMouseEnter}>
      {children}
    </a>
  );
}

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

Интеграция с асинхронными данными

Для маршрутов с loader prefetching работает следующим образом:

  1. Маршрут регистрируется с loader.
  2. При срабатывании события prefetching вызывается loader.
  3. Полученные данные кэшируются в router.state.
  4. При переходе на маршрут данные извлекаются из кэша, не выполняя повторный запрос.

Пример с асинхронным API:

const dashboardRoute = Route({
  path: '/dashboard',
  loader: async () => {
    const res = await fetch('/api/dashboard');
    if (!res.ok) throw new Error('Ошибка загрузки данных');
    return res.json();
  },
  prefetch: 'hover',
});

Комбинация prefetching с ленивой загрузкой компонентов

Для ленивых компонентов prefetching позволяет уменьшить perceptual delay:

const Reports = lazy(() => import('./Reports'));

const reportsRoute = Route({
  path: '/reports',
  component: Reports,
  prefetch: 'visible',
});

TanStack Router автоматически инициирует загрузку компонента при срабатывании триггера prefetch.

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

  • Aggressive prefetching — загрузка всех маршрутов при первой загрузке приложения. Используется редко, так как может создавать лишнюю нагрузку на сеть.
  • On-demand prefetching — загрузка маршрутов по действиям пользователя (hover, intent, visible). Баланс между производительностью и экономией ресурсов.
  • Priority prefetching — маршруты высокого приоритета загружаются первыми, остальные — по мере доступности сети.

Кэширование и повторное использование данных

TanStack Router использует внутренний кэш для prefetching:

  • Данные маршрута и компоненты хранятся в памяти.
  • Повторная навигация не инициирует загрузку заново.
  • Можно вручную сбросить кэш через методы router.clearPrefetchCache() или router.reloadRoute(routeId).

Практические советы

  1. Для маршрутов с большим количеством данных лучше использовать стратегию intent или visible, чтобы не перегружать сеть.
  2. Для часто посещаемых страниц можно комбинировать hover и loader prefetching для мгновенного отображения.
  3. Prefetching компонентов и данных можно синхронизировать через общий контекст состояния, чтобы избежать двойных запросов.
  4. Для SEO-маршрутов prefetching не влияет на серверный рендер, так как инициируется на клиенте.

Выводы по эффективности

Prefetching маршрутов в TanStack Router снижает latency при переходах, повышает отзывчивость интерфейса и улучшает пользовательский опыт. Оптимальная стратегия зависит от размера приложения, сетевой нагрузки и характера пользовательских действий.

Хотите, я могу подготовить подробную схему схему потоков данных prefetching с визуализацией кэша и асинхронных loader’ов, чтобы наглядно показать, как это работает внутри TanStack Router?