В Mapbox GL JS карта рассматривается как контейнер для набора взаимосвязанных ресурсов: источников данных (sources), слоёв (layers), изображений (images), шрифтовых глифов (glyphs), тайлов и стилей. Каждый из этих компонентов существует в рамках состояния карты и может динамически добавляться, обновляться или удаляться.
Ключевой особенностью архитектуры является строгая связность слоёв и источников: слой не может существовать без источника, а удаление источника при наличии зависимых слоёв приводит к ошибкам выполнения. Поэтому управление удалением ресурсов требует соблюдения порядка операций и понимания зависимостей внутри стиля.
Источники данных представляют собой фундаментальный уровень абстракции. Они определяют, откуда поступают геоданные:
Каждый источник регистрируется в стиле карты и получает уникальный идентификатор.
Основные операции:
map.addSource('cities', {
type: 'geojson',
data: '/data/cities.geojson'
});
Удаление источника выполняется через:
map.removeSource('cities');
Удаление источника возможно только при отсутствии зависимых слоёв. При нарушении этого условия возникает ошибка, поскольку слои продолжают ссылаться на удалённый объект.
Типичная последовательность корректного удаления:
if (map.getLayer('cities-layer')) {
map.removeLayer('cities-layer');
}
if (map.getSource('cities')) {
map.removeSource('cities');
}
Слои представляют визуальное отображение данных источника. Каждый слой связан с конкретным источником и определяет:
Добавление слоя:
map.addLayer({
id: 'cities-layer',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': 6,
'circle-color': '#ff0000'
}
});
Удаление слоя:
map.removeLayer('cities-layer');
Слои в стиле формируют стек отрисовки. Удаление должно учитывать:
При наличии нескольких слоёв на одном источнике удаление источника возможно только после удаления всех слоёв.
Mapbox GL JS поддерживает использование пользовательских изображений в символических слоях. Эти изображения добавляются в глобальный реестр стиля:
map.addImage('marker-icon', imageData);
Использование в слое:
map.addLayer({
id: 'points',
type: 'symbol',
source: 'points',
layout: {
'icon-image': 'marker-icon'
}
});
Удаление изображения:
map.removeImage('marker-icon');
Удаление изображения возможно только при отсутствии ссылок на него в слоях. Если изображение используется, операция приведёт к ошибке.
Практика безопасного удаления включает:
Глифы используются для рендеринга текста в symbol слоях. Они загружаются из font stacks, указанных в стиле карты.
Пример конфигурации:
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
Удаление глифов напрямую не выполняется через API Mapbox GL JS, поскольку они управляются стилем. Управление осуществляется через:
Метод setStyle полностью заменяет текущий стиль карты,
включая:
map.setStyle('mapbox://styles/mapbox/light-v11');
При вызове setStyle происходит:
Важно учитывать, что асинхронная природа загрузки стиля требует
повторной регистрации пользовательских ресурсов после события
style.load.
map.on('style.load', () => {
map.addSource('custom', {...});
map.addLayer({...});
});
Жизненный цикл карты включает несколько стадий:
При уничтожении карты:
map.remove();
Происходит:
Однако в прикладной логике часто требуется дополнительная очистка внешних ссылок, особенно при использовании фреймворков.
Утечки памяти в Mapbox GL JS чаще всего возникают не внутри карты, а на уровне приложения.
Основные источники:
Подписки на события должны сопровождаться обязательным удалением:
function onMove() {
// обработка
}
map.on('move', onMove);
map.off('move', onMove);
Особенно критично это при частом создании и уничтожении карты (SPA).
При работе с realtime данными часто используются:
setData для GeoJSON источниковmap.getSource('track').setData(newData);
При остановке потока данных требуется:
clearInterval(updateTimer);
if (map.getLayer('track-layer')) {
map.removeLayer('track-layer');
}
if (map.getSource('track')) {
map.removeSource('track');
}
В архитектурах на React, Vue или аналогичных системах критично учитывать повторное создание карты.
Типичный сценарий:
useEffect(() => {
const map = new mapboxgl.Map({ ... });
return () => {
map.remove();
};
}, []);
При отсутствии корректного удаления возникают:
Корректный порядок удаления обеспечивает отсутствие ошибок:
Нарушение порядка приводит к каскадным ошибкам зависимостей, особенно при сложных стилях с множеством слоёв.
В устойчивых приложениях используется централизованное управление ресурсами:
Типовой подход включает реестр ресурсов:
const registry = {
layers: [],
sources: [],
images: []
};
Это позволяет выполнять детерминированную очистку без обхода всего стиля карты.
Векторные источники чаще имеют несколько слоёв-потребителей, что усложняет удаление.
Растровые источники могут использоваться в фонах и требуют проверки на:
Удаление таких источников выполняется только после полной проверки всех зависимостей в стиле.
В длительно работающих приложениях (дашборды, мониторинг, трекинг) наблюдается накопление:
Периодическая очистка выполняется через:
Такой подход предотвращает деградацию производительности WebGL и утечки памяти на уровне браузера.