Ленивая загрузка маршрутов
Если приложение большое, весь код грузить сразу невыгодно. Пользователь ждёт, пока загрузится код страниц, которые он, возможно, никогда не откроет.
Ленивая загрузка (code splitting) разбивает бандл на части. Каждая часть грузится при переходе на маршрут.
React.lazy
import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Posts = lazy(() => import('./pages/Posts'));
function App() {
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/posts" element={<Posts />} />
</Routes>
</Suspense>
);
}
lazy — динамический импорт. Suspense — показывает fallback, пока компонент грузится.
Компонент должен экспортироваться по умолчанию
// pages/Home.tsx
export default function Home() {
return <h1>Главная</h1>;
}
Разные fallback
<Suspense fallback={<PageSpinner />}>
<Routes>
{/* ... */}
</Routes>
</Suspense>
Можно оборачивать каждый маршрут отдельно, если нужен разный fallback.
Предзагрузка
React Router v7 предоставляет API для предзагрузки. Также можно вручную:
const Posts = lazy(() => import('./pages/Posts'));
// Предзагрузка при наведении
<Link to="/posts" onMouseEnter={() => import('./pages/Posts')}>
Посты
</Link>
Группировка
Не всё нужно разбивать. Мелкие компоненты лучше держать в основном бандле. Разбивай страницы.
App.tsx — корень, роутер
pages/Home.tsx — отдельный чанк
pages/Posts.tsx — отдельный чанк
pages/About.tsx — отдельный чанк
Проверка бандла
npm run build
Vite покажет список чанков и их размер.
React Router v7 и lazy
В v7 можно объявить лениво прямо в маршруте:
const router = createBrowserRouter([
{
path: '/',
lazy: () => import('./pages/Home'),
},
]);
Или через route.lazy.
Анализ бандла
Полезные инструменты:
rollup-plugin-visualizerдля Vitevite-bundle-visualizer
Показывают, что занимает место в бандле.
Итоги
React.lazy+Suspenseдля code splittinglazy(() => import(...))для динамического импорта- Fallback на время загрузки
- Разбивай страницы, не компоненты
- Предзагрузка при наведении
- Анализируй бандл