Navigo — это легковесный роутер для JavaScript, предназначенный для одностраничных приложений (SPA). Одной из важных задач при работе с маршрутами является оптимизация производительности через кеширование данных, загружаемых при переходах между маршрутами. Кеширование позволяет сократить количество сетевых запросов, ускорить отображение страниц и уменьшить нагрузку на сервер.
В контексте Navigo кеширование может применяться на нескольких уровнях:
Кеширование результатов сетевых запросов Часто
маршруты загружают данные через API. Вместо повторного запроса при
каждом переходе можно сохранять результат в объекте или
Map, связав его с ключом маршрута.
const routeCache = new Map();
function fetchData(routeKey, fetchFunction) {
if (routeCache.has(routeKey)) {
return Promise.resolve(routeCache.get(routeKey));
}
return fetchFunction().then(data => {
routeCache.set(routeKey, data);
return data;
});
}
router.on('/users', () => {
fetchData('users', () => fetch('/api/users').then(res => res.json()))
.then(users => renderUsers(users));
});
В этом примере данные пользователей кешируются после первого запроса.
Последующие переходы на /users используют кеш.
Кеширование шаблонов и компонентов Если приложение использует динамические компоненты или шаблоны, их можно хранить в памяти после первого рендера. Это особенно полезно при использовании client-side rendering.
const templateCache = {};
function loadTemplate(name, fetchTemplate) {
if (!templateCache[name]) {
templateCache[name] = fetchTemplate();
}
return templateCache[name];
}
router.on('/dashboard', () => {
const template = loadTemplate('dashboard', () => fetch('/templates/dashboard.html').then(res => res.text()));
template.then(html => render(html));
});
Такой подход снижает задержку при повторном рендере страниц.
Кеширование без ограничений может привести к чрезмерному потреблению памяти. Поэтому необходимо применять стратегии управления кешем:
TTL (Time to Live) — хранение данных только ограниченное время:
const cacheTTL = new Map();
function setCacheWithTTL(key, value, ttl = 60000) {
cacheTTL.set(key, { value, expiry: Date.now() + ttl });
}
function getCacheWithTTL(key) {
const cached = cacheTTL.get(key);
if (cached && cached.expiry > Date.now()) {
return cached.value;
}
cacheTTL.delete(key);
return null;
}Ленивое удаление (Lazy Eviction) — удаление устаревших данных при следующем доступе к кешу.
LRU (Least Recently Used) — хранение ограниченного количества элементов, удаляя наименее используемые.
Navigo предоставляет возможность обрабатывать маршруты через функции-обработчики. Кеш можно интегрировать на этапе вызова обработчика маршрута или загрузки данных:
router.on('/products/:id', (params) => {
const key = `product_${params.id}`;
fetchData(key, () => fetch(`/api/products/${params.id}`).then(res => res.json()))
.then(product => renderProduct(product));
});
В этом примере данные конкретного продукта кешируются по уникальному
ключу, составленному из маршрута и параметра id.
Маршруты с динамическими параметрами требуют генерации уникальных ключей кеша. Например:
/posts/1 → post_1/posts/2 → post_2function getRouteKey(route, params) {
return `${route}_${Object.values(params).join('_')}`;
}
router.on('/posts/:postId', (params) => {
const key = getRouteKey('posts', params);
fetchData(key, () => fetch(`/api/posts/${params.postId}`).then(res => res.json()))
.then(post => renderPost(post));
});
Такой подход предотвращает перезапись кеша для разных параметров одного маршрута.
Для улучшения UX можно реализовать предзагрузку данных маршрутов, которые пользователь с высокой вероятностью посетит. Это делается через асинхронное сохранение данных в кеш:
function preloadRouteData(routeKey, fetchFunction) {
fetchFunction().then(data => routeCache.set(routeKey, data));
}
// Предварительная загрузка списка товаров
preloadRouteData('products', () => fetch('/api/products').then(res => res.json()));
Предзагрузка позволяет моментально отображать страницы без ожидания сетевых запросов.
Иногда важно показывать свежие данные, но при этом использовать кеш для скорости. Эту задачу решают стратегии stale-while-revalidate:
function fetchWithRevalidate(key, fetchFunction, render) {
const cached = routeCache.get(key);
if (cached) render(cached);
fetchFunction().then(data => {
routeCache.set(key, data);
if (!cached) render(data); // Если данных не было в кеше, рендерим сразу
else render(data); // Если были устаревшие данные, обновляем
});
}
Этот подход обеспечивает баланс между производительностью и актуальностью информации.
Для долгоживущих приложений важно контролировать размер кеша:
Эффективное кеширование маршрутов в Navigo существенно ускоряет SPA и повышает отзывчивость приложения без изменения структуры роутера.