Ленивая инициализация — это механизм, позволяющий откладывать создание или вычисление маршрута до момента фактического его запроса. В контексте Universal Router это особенно полезно для больших приложений с множеством маршрутов, где загрузка всех компонентов сразу увеличивает время старта приложения и потребление памяти.
В Universal Router маршруты задаются как объекты с ключами
path и action. Для ленивой инициализации
ключевую роль играет отложенный вызов функции
action, который возвращает компонент или результат
только при необходимости.
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/home',
action: () => import('./pages/Home.js').then(module => module.default)
},
{
path: '/profile/:id',
action: async ({ params }) => {
const module = await import('./pages/Profile.js');
return module.default(params.id);
}
}
];
const router = new UniversalRouter(routes);
В этом примере:
import() используется для динамической подгрузки
модулей.action вызывается только тогда, когда
пользователь переходит по соответствующему пути.:id, автоматически
передаются в функцию, обеспечивая доступ к динамическим значениям.Universal Router поддерживает вложенные маршруты, что позволяет организовать иерархию приложения. Для ленивой инициализации можно откладывать не только основной компонент, но и дочерние маршруты.
const routes = [
{
path: '/dashboard',
action: () => import('./pages/Dashboard.js').then(module => module.default),
children: [
{
path: '/analytics',
action: () => import('./pages/DashboardAnalytics.js').then(m => m.default)
},
{
path: '/settings',
action: () => import('./pages/DashboardSettings.js').then(m => m.default)
}
]
}
];
Особенности:
Ленивая инициализация часто предполагает асинхронные действия,
например, загрузку данных перед отображением компонента. В
action можно использовать async/await для
упрощения работы с промисами.
const routes = [
{
path: '/posts/:postId',
async action({ params }) {
const { default: Post } = await import('./pages/Post.js');
const postData = await fetch(`/api/posts/${params.postId}`).then(r => r.json());
return Post(postData);
}
}
];
Здесь:
Можно смешивать ленивую и обычную инициализацию в одном роутере. Это полезно для маршрутов, которые часто посещаются и должны загружаться сразу, и редких маршрутов, которые можно подгружать по необходимости.
const routes = [
{
path: '/',
action: () => import('./pages/Home.js').then(m => m.default) // часто посещаемый маршрут
},
{
path: '/admin',
action: () => import('./pages/Admin.js').then(m => m.default) // ленивый маршрут
}
];
Принцип:
resolveRoute для сложных сценариевДля сложных приложений с динамическими условиями можно использовать
метод resolveRoute:
const router = new UniversalRouter(routes, {
resolveRoute: (route, context) => {
if (route.load) {
return route.load().then(module => {
route.action = module.default;
return module.default(context);
});
}
return route.action ? route.action(context) : undefined;
}
});
resolveRoute позволяет внедрять кастомную логику
загрузки маршрутов.При использовании ленивой инициализации важно учитывать несколько моментов:
preload) —
можно заранее загрузить критические маршруты без рендеринга, если
известно, что пользователь скоро перейдет по ним.import() позволяет Webpack и другим сборщикам создавать
отдельные чанки, уменьшая размер основного бандла.Параметры маршрута передаются в функцию action через
объект context.params:
{
path: '/user/:userId',
async action({ params }) {
const { default: User } = await import('./pages/User.js');
const userData = await fetch(`/api/users/${params.userId}`).then(r => r.json());
return User(userData);
}
}
:userId), так
и звездочные (*) маршруты для catch-all случаев.Universal Router легко интегрируется с React, Vue или Svelte, позволяя лениво подгружать компоненты:
const routes = [
{
path: '/react-page',
action: () => import('./components/ReactPage.jsx').then(m => m.ReactPage)
}
];
Ленивая инициализация в Universal Router обеспечивает эффективное управление ресурсами, ускоряет рендеринг и позволяет строить масштабируемые маршрутизаторы даже для больших SPA-приложений.