В библиотеке Navigo маршрутизация строится на
привязке URL-путей к обработчикам функций. При работе с большими
приложениями возникает необходимость загружать модули только по
мере необходимости, чтобы минимизировать начальный вес бандла.
Для этого применяется динамический импорт модулей, встроенный в
современный JavaScript через конструкцию import().
import Navigo from 'navigo';
const router = new Navigo('/', { hash: true });
Маршрут можно определить с асинхронной загрузкой модуля следующим образом:
router.on('/dashboard', async () => {
const module = await import('./views/dashboard.js');
module.renderDashboard();
});
Здесь ключевым моментом является использование async
функции и await import(). Модуль загружается только при
переходе на маршрут /dashboard, что сокращает время
первоначальной загрузки страницы и экономит ресурсы.
Navigo позволяет определять маршруты с динамическими параметрами, что удобно комбинировать с динамическим импортом:
router.on('/profile/:userId', async ({ data }) => {
const { userId } = data;
const module = await import('./views/profile.js');
module.renderProfile(userId);
});
В этом примере при переходе на /profile/123 загружается
модуль profile.js, и функция renderProfile
получает конкретный userId. Использование параметров
маршрута совместно с динамическим импортом позволяет строить
модульные и масштабируемые приложения.
Динамический импорт может завершиться ошибкой, например, если модуль
отсутствует. Для безопасной загрузки рекомендуется оборачивать вызов в
try...catch:
router.on('/settings', async () => {
try {
const module = await import('./views/settings.js');
module.renderSettings();
} catch (err) {
console.error('Ошибка загрузки модуля:', err);
document.body.innerHTML = '<h1>Не удалось загрузить страницу настроек</h1>';
}
});
Такой подход предотвращает падение всего приложения при ошибке импорта и позволяет предоставить альтернативный пользовательский интерфейс.
Для удобства организации больших проектов можно использовать динамические пути при импорте модулей. Например, если у приложения есть множество страниц в одной папке:
async function loadPage(page) {
try {
const module = await import(`./views/${page}.js`);
module.render();
} catch (err) {
console.error(`Не удалось загрузить страницу ${page}`, err);
}
}
router.on('/:page', ({ data }) => loadPage(data.page));
Такой подход позволяет загружать нужные модули по шаблону имени страницы, сводя к минимуму ручное перечисление всех маршрутов.
При динамическом импорте модулей важно помнить, что часто нужны не только JS, но и CSS или другие ресурсы. С современными сборщиками, такими как Webpack или Vite, можно импортировать CSS вместе с модулем:
router.on('/analytics', async () => {
const module = await import('./views/analytics.js');
await import('./views/analytics.css');
module.renderAnalytics();
});
Это позволяет подгружать стили только для активной страницы, что улучшает производительность и уменьшает ненужные сетевые запросы.
Иногда полезно заранее загрузить модули, которые с высокой вероятностью будут использованы. Для этого используется prefetch с динамическим импортом:
const prefetchDashboard = () => import('./views/dashboard.js');
router.on('/home', () => {
prefetchDashboard(); // загружаем Dashboard в фоновом режиме
// отображаем домашнюю страницу
});
При этом модуль уже будет доступен в кэше браузера, когда
пользователь перейдет на /dashboard. Этот подход позволяет
сочетать ленивую загрузку с повышенной отзывчивостью
интерфейса.
Динамический импорт легко интегрируется с:
router.navigate('/dashboard') после успешного импорта
модуля.{ hash: true } при инициализации Navigo не мешает
асинхронным загрузкам.router.notFound(async () => {
const module = await import('./views/404.js');
module.renderNotFound();
});
async/await с динамическим импортом
для чистого и понятного кода.try...catch для обработки
ошибок.Динамический импорт в Navigo превращает маршрутизацию в мощный инструмент для построения масштабируемых SPA, позволяя оптимизировать загрузку и управление ресурсами на каждом этапе пользовательского взаимодействия.