В Universal Router предзагрузка данных (data preloading) позволяет получать необходимые ресурсы до того, как компонент будет отрендерен. Это особенно важно для SPA-приложений, где требуется минимизировать задержку отображения страницы и обеспечить пользователю мгновенный доступ к контенту.
Каждый маршрут в Universal Router может содержать асинхронный
обработчик через функцию action. Она может
возвращать данные напрямую или через промис. Пример базового маршрута с
предзагрузкой данных:
import UniversalRouter from 'universal-router';
const routes = [
{
path: '/users/:id',
async action({ params, query }) {
const response = await fetch(`/api/users/${params.id}`);
const user = await response.json();
return { user };
}
}
];
const router = new UniversalRouter(routes);
router.resolve({ pathname: '/users/42' }).then(result => {
console.log(result.user);
});
Здесь action асинхронно загружает данные пользователя и
возвращает объект, который затем может использоваться для рендеринга
страницы.
Universal Router передает в action объект с ключевыми
параметрами:
pathname — текущий путь.params — параметры маршрута, определённые в пути
(:id, :slug и т.д.).query — объект с параметрами запроса.route — текущий маршрут.context — объект контекста, передаваемый в
resolve.Использование params и context позволяет
создавать универсальные функции предзагрузки данных,
которые могут использоваться на нескольких маршрутах.
async function loadUser({ params }) {
const response = await fetch(`/api/users/${params.id}`);
return response.json();
}
const routes = [
{
path: '/users/:id',
async action(ctx) {
const user = await loadUser(ctx);
return { user };
}
}
];
Часто требуется загрузка нескольких ресурсов одновременно. Для этого
удобно использовать Promise.all:
const routes = [
{
path: '/dashboard',
async action() {
const [usersResponse, statsResponse] = await Promise.all([
fetch('/api/users'),
fetch('/api/stats')
]);
const users = await usersResponse.json();
const stats = await statsResponse.json();
return { users, stats };
}
}
];
Такой подход обеспечивает параллельную загрузку данных, что ускоряет рендеринг страницы.
Контекст Universal Router позволяет передавать данные между маршрутами, избегая повторных запросов. Пример:
const context = { cache: new Map() };
const routes = [
{
path: '/products/:id',
async action({ params, context }) {
if (context.cache.has(params.id)) {
return context.cache.get(params.id);
}
const response = await fetch(`/api/products/${params.id}`);
const product = await response.json();
context.cache.set(params.id, { product });
return { product };
}
}
];
const router = new UniversalRouter(routes, { context });
В этом примере данные продукта кэшируются в
context.cache и используются при повторных обращениях к
маршруту.
Иногда нужно не только предзагрузить данные, но и динамически импортировать компонент после их получения:
const routes = [
{
path: '/profile/:id',
async action({ params }) {
const response = await fetch(`/api/profile/${params.id}`);
const profile = await response.json();
const ProfileComponent = (await import('./Profile.js')).default;
return { component: ProfileComponent, profile };
}
}
];
Такой подход позволяет реализовать code splitting, когда компонент загружается только при необходимости, вместе с его данными.
В больших приложениях удобно создавать глобальные функции предзагрузки, которые вызываются для всех маршрутов до рендеринга. Например, для проверки авторизации:
async function preloadAuth({ context }) {
if (!context.user) {
const response = await fetch('/api/auth/me');
context.user = await response.json();
}
}
const routes = [
{
path: '/settings',
async action(ctx) {
await preloadAuth(ctx);
return { settings: await fetchSettings() };
}
}
];
Такой подход обеспечивает централизованную логику загрузки и проверку условий для всех маршрутов.
Предзагрузка данных особенно актуальна для SSR. Universal Router позволяет резолвить маршруты на сервере, загружая все данные до передачи HTML клиенту:
const context = {};
const routeData = await router.resolve({ pathname: '/users/1', context });
// routeData содержит все данные для рендеринга на сервере
Это позволяет клиенту получать полностью готовую страницу без лишней задержки на асинхронную загрузку.
context для повторного
использования.Promise.all для параллельной загрузки
нескольких ресурсов.action для
предотвращения прерывания маршрута.Эффективная предзагрузка данных в Universal Router делает SPA более отзывчивым, ускоряет время первого рендеринга и облегчает интеграцию с серверным рендерингом.