React Router предоставляет мощный инструмент для организации навигации в приложениях на React. Одной из ключевых техник оптимизации является lazy loading — отложенная загрузка компонентов маршрутов, которая позволяет уменьшить первоначальный размер бандла и ускорить загрузку страницы.
Lazy loading позволяет загружать компоненты только в момент их фактической необходимости. В контексте маршрутов это означает, что компонент, связанный с конкретным маршрутом, не будет загружен при старте приложения, а только когда пользователь перейдет по этому маршруту.
Для реализации lazy loading используется стандартная функция
React.lazy и компонент Suspense:
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Contact = lazy(() => import('./pages/Contact'));
function App() {
return (
<Router>
<Suspense fallback={<div>Загрузка...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</Suspense>
</Router>
);
}
export default App;
Ключевые моменты:
React.lazy(() => import('./Component')) создаёт
динамический импорт компонента.Suspense оборачивает маршруты, предоставляя
UI-резерв (fallback) на время загрузки.React Router поддерживает вложенные маршруты, которые также можно загружать лениво. Для этого lazy компоненты размещаются на уровне вложенного маршрута:
const Dashboard = lazy(() => import('./pages/Dashboard'));
const DashboardHome = lazy(() => import('./pages/DashboardHome'));
const DashboardSettings = lazy(() => import('./pages/DashboardSettings'));
function App() {
return (
<Router>
<Suspense fallback={<div>Загрузка...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />}>
<Route index element={<DashboardHome />} />
<Route path="settings" element={<DashboardSettings />} />
</Route>
</Routes>
</Suspense>
</Router>
);
}
Особенности:
<Outlet /> для рендеринга дочерних компонентов.Маршруты с динамическими параметрами (:id,
:slug) полностью совместимы с lazy loading. Динамический
импорт компонента не зависит от параметров:
const UserProfile = lazy(() => import('./pages/UserProfile'));
function App() {
return (
<Router>
<Suspense fallback={<div>Загрузка профиля...</div>}>
<Routes>
<Route path="/user/:id" element={<UserProfile />} />
</Routes>
</Suspense>
</Router>
);
}
Особенности работы:
UserProfile не загружается до перехода на
путь /user/:id.id доступен через хук
useParams.Для улучшения пользовательского опыта иногда требуется предзагружать
компоненты заранее, например при наведении на ссылку. Для этого можно
использовать динамический импорт с функцией preload:
const About = lazy(() => import('./pages/About'));
function preloadAbout() {
import('./pages/About');
}
preloadAbout() не рендерит компонент, но
загружает его в бандл.<Link> или в
момент, когда пользователь приближается к нужному разделу.При динамической загрузке могут возникать ошибки сети или другие
исключения. Для их обработки рекомендуется использовать
компонент-обёртку с ErrorBoundary:
import ErrorBoundary from './components/ErrorBoundary';
function App() {
return (
<Router>
<ErrorBoundary>
<Suspense fallback={<div>Загрузка...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</ErrorBoundary>
</Router>
);
}
ErrorBoundary перехватывает ошибки при загрузке
ленивого компонента и позволяет показывать кастомный UI.Suspense создаётся надёжная система
отложенной загрузки.Lazy loading компонентов маршрутов в React Router повышает производительность приложений, сокращает время первой загрузки и создаёт более отзывчивый интерфейс. Правильная организация маршрутов с отложенной загрузкой особенно важна в крупных приложениях с множеством страниц и динамическим контентом.