В веб-картах на базе Mapbox GL JS производительность во многом определяется тем, насколько заранее загружены тайлы, спрайты и шрифты. Поведение загрузки в этой библиотеке ленивое: данные подгружаются по мере приближения камеры к соответствующим координатам и зумам. Это снижает начальный трафик, но может приводить к «пустым» областям при резких перемещениях карты. Управление предварительной загрузкой тайлов становится ключевым инструментом оптимизации UX.
Внутренняя логика загрузки в Mapbox GL JS основана на:
Каждое движение камеры инициирует перерасчёт видимых тайлов. Однако библиотека также использует prefetch-зону — расширенную область вокруг viewport, где тайлы загружаются заранее.
Основной механизм предварительной загрузки тайлов — параметр
prefetchZoomDelta.
Он определяет, на сколько уровней масштабирования «вперёд» будут подгружаться тайлы.
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [69.2401, 41.2995],
zoom: 10,
prefetchZoomDelta: 3
});
0 — подгружается только текущий zoom1–2 — умеренное предзагружение (баланс)3–4 — агрессивная предзагрузкаПри увеличении zoom пользователю кажется, что карта «мгновенно» отрисовывается, поскольку тайлы уже находятся в кеше.
Mapbox GL JS хранит тайлы в памяти, используя внутренний LRU-кэш.
Ключевые факторы:
map.addControl(new mapboxgl.NavigationControl());
map.setMaxTileCacheSize && map.setMaxTileCacheSize(200);
В некоторых версиях управление размером кэша реализовано косвенно через параметры производительности и ограничение области отображения.
Сильное влияние на предзагрузку оказывает ограничение географии карты.
map.setMaxBounds([
[68.0, 40.0],
[71.0, 42.5]
]);
Эффект:
Это особенно важно для специализированных приложений (логистика, городские сервисы).
idleОдним из ключевых инструментов является событие idle,
сигнализирующее, что:
map.on('idle', () => {
console.log('карта полностью загружена');
});
Это событие часто используется для запуска дополнительных стратегий предзагрузки.
Хотя библиотека не предоставляет прямого API
preloadTiles, эффект можно добиться искусственно изменяя
состояние камеры.
async function warmUp(map) {
const startZoom = map.getZoom();
for (let z = startZoom; z <= startZoom + 2; z += 0.5) {
map.easeTo({ zoom: z, duration: 0 });
await new Promise(r => setTimeout(r, 50));
}
map.easeTo({ zoom: startZoom, duration: 0 });
}
Поведение:
При работе с анимациями (flyTo, easeTo) полезно заранее загружать тайлы целевой области.
map.flyTo({
center: [69.5, 41.3],
zoom: 12,
essential: true
});
Чтобы усилить эффект предзагрузки, применяют «двойной проход»:
map.jumpTo({ center: target, zoom: 12 });
map.jumpTo({ center: start, zoom: 10 });
map.flyTo({ center: target, zoom: 12 });
Один из наиболее стабильных методов — создание второго экземпляра карты.
const preloadMap = new mapboxgl.Map({
container: document.createElement('div'),
style: 'mapbox://styles/mapbox/streets-v12',
center: [69.2401, 41.2995],
zoom: 12,
interactive: false,
prefetchZoomDelta: 4
});
Особенности:
Этот подход эффективен для SPA-приложений.
Тайлы — не единственный источник задержек. Стиль карты включает:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
transformRequest: (url, resourceType) => {
return {
url,
headers: {
'x-preload': '1'
}
};
}
});
Это позволяет:
Даже при оптимальной настройке Mapbox GL JS критично поведение HTTP-кеша:
Cache-Control: max-ageETagТайлы, спрайты и glyphs повторно используются между сессиями, если сервер настроен корректно.
Предзагрузка всегда является компромиссом:
prefetchZoomDeltaПлюсы:
Минусы:
Плюсы:
Минусы:
При частом pan/zoom библиотека:
Однако при слабом интернете может возникать эффект «размытого прогрева», когда низкоуровневые тайлы остаются дольше.
Предзагрузка тайлов тесно связана с:
При переполнении кэша:
Это важно учитывать при больших zoom (>14) и высоких разрешениях экранов.
Типичная стратегия ускорения первой отрисовки:
Эти ошибки приводят к нестабильному потреблению памяти и деградации производительности вместо её улучшения