MapLibre GL JS опирается на многоуровневую систему кэширования, которая обеспечивает плавную работу интерактивных карт, минимизирует сетевые запросы и снижает нагрузку на тайл-серверы. Основная модель рендеринга построена вокруг векторных тайлов, стилей, шрифтов и растровых ресурсов (спрайтов), каждый из которых может кэшироваться независимо.
Ключевая особенность архитектуры заключается в разделении ответственности между браузером, сетевым стеком и внутренними механизмами MapLibre. В результате кэширование происходит одновременно на нескольких уровнях:
transformRequestНаиболее значимый уровень кэширования в MapLibre GL JS — стандартный HTTP-кэш браузера. Каждый запрос к тайлам, спрайтам или шрифтам сопровождается заголовками, определяющими поведение кэширования:
Cache-ControlETagLast-ModifiedExpiresВекторные тайлы обычно отдаются с долгим временем жизни кэша, поскольку они редко изменяются. Типичный URL тайла выглядит следующим образом:
https://tiles.example.com/14/4823/6160.pbf
Браузер сохраняет такие ответы в дисковом или memory cache, что позволяет повторно использовать их при панорамировании и зуме без повторных запросов.
Особое значение имеет правильная настройка
Cache-Control:
Cache-Control: public, max-age=86400, immutable
Использование immutable позволяет браузеру полностью
исключить повторную валидацию ресурса в течение срока жизни кэша.
Помимо HTTP-кэша, MapLibre GL JS использует собственный механизм хранения тайлов в памяти. Этот кэш предназначен для ускорения перерисовки карты при:
Тайлы сохраняются в памяти в декодированном виде (после парсинга PBF), что позволяет избежать повторной десериализации и ускоряет GPU-пайплайн.
Управление этим кэшем происходит через параметры
Map:
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
maxTileCacheSize: 512
});
Параметр maxTileCacheSize определяет количество тайлов,
удерживаемых в памяти. При превышении лимита используется стратегия
вытеснения (LRU — least recently used), при которой наименее
используемые тайлы удаляются первыми.
Стиль в MapLibre GL JS представляет собой JSON-документ, который описывает:
После загрузки стиль кешируется в памяти и не пересобирается при каждом изменении состояния карты. Внутри движка происходит разделение на:
Особенно важен кэш спрайтов и глифов, так как они являются отдельными сетевыми ресурсами.
Спрайты представляют собой набор иконок, используемых для символических слоёв. MapLibre загружает два файла:
sprite.png или sprite@2x.pngsprite.jsonПосле загрузки изображения оно кэшируется в WebGL-текстуре, что позволяет использовать иконки без повторной загрузки или декодирования.
Пример ссылки:
https://tiles.example.com/sprites/sprite
Система кэширования спрайтов работает следующим образом:
При потере WebGL-контекста спрайты загружаются повторно, но при сохранении контекста повторных загрузок не происходит.
Шрифты в MapLibre GL JS представляют собой растровые глифы, разбитые на диапазоны символов. URL обычно выглядит так:
https://tiles.example.com/fonts/{fontstack}/{range}.pbf
Каждый диапазон символов (например, 0–255) загружается отдельно и кэшируется.
Механизм работы:
Это критично для языков с большим набором символов, где повторное использование диапазонов существенно снижает нагрузку.
MapLibre использует предзагрузку тайлов вокруг текущего viewport. Это создаёт эффект «буфера» данных, который уменьшает задержки при перемещении карты.
Алгоритм:
Важным параметром является renderWorldCopies, который
влияет на количество дублируемых тайлов мира. При включённом значении
увеличивается объём кэша, но улучшается непрерывность отображения.
Одним из наиболее мощных инструментов контроля кэширования является
функция transformRequest. Она позволяет изменять параметры
каждого сетевого запроса.
Пример:
const map = new maplibregl.Map({
container: 'map',
style: 'https://example.com/style.json',
transformRequest: (url, resourceType) => {
if (resourceType === 'Tile') {
return {
url: url + '?cacheBust=' + Date.now()
};
}
}
});
Хотя такой подход может отключать кэширование, он используется в сценариях:
При неправильном использовании transformRequest может
полностью разрушить эффективность HTTP-кэша.
Векторные тайлы (.pbf) проходят несколько стадий обработки:
MapLibre кэширует результат декодирования, а не только сырой ответ. Это ключевое отличие от классического HTTP-кэша.
Такая стратегия позволяет:
Изменение стиля через setStyle приводит к частичной или
полной очистке кэша:
map.setStyle('https://example.com/new-style.json');
В результате:
Такое поведение связано с тем, что стиль определяет структуру источников данных, и старые тайлы могут быть несовместимы с новой схемой.
MapLibre GL JS реализует дедупликацию сетевых запросов. Если несколько слоёв запрашивают один и тот же тайл одновременно, создаётся один HTTP-запрос, а результат распределяется между потребителями.
Это достигается через внутренний request scheduler:
Такой подход уменьшает количество сетевых соединений и повышает стабильность при медленных сетях.
Встроенный MapLibre GL JS не содержит полноценного оффлайн-хранилища, но предоставляет точки расширения для реализации собственных решений:
Типичная реализация через Service Worker:
self.addEventListener('fetch', event => {
if (event.request.url.includes('/tiles/')) {
event.respondWith(
caches.open('tiles-cache').then(cache => {
return cache.match(event.request).then(response => {
return response || fetch(event.request).then(networkResponse => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
});
})
);
}
});
Такая схема позволяет полностью автономно использовать карты без постоянного сетевого доступа.
Кэширование требует строгого контроля версионности данных. Основные стратегии инвалидации:
/tiles/v2/{z}/{x}/{y}.pbf)?v=123)Наиболее устойчивой практикой является использование версионированных путей, так как они полностью исключают неоднозначность между старыми и новыми данными.
Эффективность MapLibre GL JS напрямую зависит от баланса между:
Слишком агрессивное кэширование приводит к росту потребления памяти, а слишком слабое — к деградации UX из-за повторных запросов и перекодирования.
Оптимальная стратегия обычно включает:
maxTileCacheSize