Экземпляр карты в Leaflet представляет собой объект класса
L.Map, который управляет контейнером карты, слоями,
обработчиками событий, элементами интерфейса и внутренними механизмами
библиотеки. После создания карта остаётся активной до тех пор, пока
существует соответствующий объект и связанные с ним ресурсы.
В долгоживущих веб-приложениях карта может многократно создаваться и удаляться. Особенно часто это происходит в:
Для корректного освобождения ресурсов Leaflet предоставляет специальный метод:
map.remove();
Данный метод полностью уничтожает карту и отключает связанные с ней механизмы.
Сигнатура метода:
map.remove();
Пример:
const map = L.map('map').setView([55.751244, 37.618423], 10);
// Работа с картой
map.remove();
После вызова метода:
Рассмотрим внутренние процессы более подробно.
Во время работы карта регистрирует множество событий:
map.on('click', handler);
map.on('zoomend', zoomHandler);
map.on('moveend', moveHandler);
После выполнения:
map.remove();
все зарегистрированные обработчики автоматически отключаются.
Дополнительный вызов:
map.off();
обычно не требуется.
Leaflet создаёт множество компонентов взаимодействия:
Например:
map.dragging.enable();
map.scrollWheelZoom.enable();
После удаления карты все эти механизмы отключаются автоматически.
Карта может содержать большое количество слоёв:
L.tileLayer(url).addTo(map);
L.marker([55.75, 37.61]).addTo(map);
L.circle([55.76, 37.62]).addTo(map);
При уничтожении карты Leaflet удаляет все зарегистрированные слои.
Пример:
const marker = L.marker([55.75, 37.61]).addTo(map);
map.remove();
Маркер перестаёт существовать в контексте карты.
Пусть карта была создана в элементе:
<div id="map"></div>
После вызова:
map.remove();
Leaflet очищает контейнер от собственных элементов:
<div id="map"></div>
Внутренние панели, тайловые контейнеры, SVG-элементы и служебные узлы удаляются.
Одна из самых распространённых причин использования
remove() — повторная инициализация карты.
const map = L.map('map');
const map2 = L.map('map');
Результат:
Map container is already initialized.
Leaflet обнаруживает, что контейнер уже связан с существующей картой.
let map = L.map('map');
map.remove();
map = L.map('map');
Теперь контейнер освобождён и может использоваться повторно.
В SPA-приложениях компоненты могут уничтожаться без обновления страницы.
Пример логики:
function destroyPage() {
map.remove();
}
При переходе на другую страницу:
destroyPage();
карта полностью освобождает ресурсы.
Без этого постепенно накапливаются:
В React карта обычно создаётся внутри useEffect.
Пример:
useEffect(() => {
const map = L.map('map').setView([55.75, 37.61], 10);
return () => {
map.remove();
};
}, []);
Функция очистки выполняется:
Это предотвращает утечки памяти.
Пример для Vue:
import { onMounted, onUnmounted } from 'vue';
let map;
onMounted(() => {
map = L.map('map');
});
onUnmounted(() => {
map.remove();
});
После удаления компонента карта корректно уничтожается.
Пример:
ngOnDestroy() {
this.map.remove();
}
Метод жизненного цикла ngOnDestroy() является
естественным местом для освобождения ресурсов.
Иногда карта может ещё не быть создана.
Небезопасный вариант:
map.remove();
Если map равно null, возникнет ошибка.
Безопасный вариант:
if (map) {
map.remove();
}
Или:
map?.remove();
После уничтожения карты повторный вызов обычно не имеет смысла.
Плохая практика:
map.remove();
map.remove();
Лучше сразу обнулить ссылку:
map.remove();
map = null;
Так становится очевидно, что объект больше не используется.
Даже после уничтожения карты переменная может продолжать хранить ссылку на объект.
Пример:
let map = L.map('map');
map.remove();
Объект уничтожен, но ссылка сохраняется.
Рекомендуемый вариант:
map.remove();
map = null;
Это помогает сборщику мусора быстрее освободить память.
Leaflet удаляет собственные обработчики карты, однако дополнительные подписки на сторонние объекты могут требовать ручной очистки.
Пример:
window.addEventListener('resize', updateMap);
Даже после:
map.remove();
обработчик окна останется активным.
Необходимо явно удалить его:
window.removeEventListener('resize', updateMap);
Предположим, карта содержит тысячи элементов:
for (let i = 0; i < 10000; i++) {
L.marker([
55 + Math.random(),
37 + Math.random()
]).addTo(map);
}
Вызов:
map.remove();
удалит все зарегистрированные слои автоматически.
Нет необходимости выполнять:
map.eachLayer(layer => {
map.removeLayer(layer);
});
непосредственно перед уничтожением всей карты.
Удаляет конкретный слой.
map.removeLayer(marker);
После выполнения:
Удаляет всю карту.
map.remove();
После выполнения:
markers.clearLayers();
Удаляются только объекты внутри группы.
Карта продолжает работать.
map.remove();
Удаляется вся инфраструктура карты.
Создание:
const map = L.map('map');
Добавление слоёв:
tileLayer.addTo(map);
marker.addTo(map);
Регистрация событий:
map.on('click', onClick);
Работа приложения:
map.setZoom(12);
Удаление:
map.remove();
map = null;
Такой сценарий считается наиболее правильным и безопасным при управлении жизненным циклом экземпляра карты Leaflet.
Всегда вызывать remove() перед удалением
контейнера карты из DOM.
map.remove();
container.remove();
Освобождать ссылку после уничтожения.
map.remove();
map = null;
Использовать очистку в хуках жизненного цикла компонентов.
return () => map.remove();
Не создавать новую карту в уже инициализированном контейнере.
map.remove();
map = L.map('map');
Удалять сторонние обработчики событий отдельно, если они были созданы вручную.
window.removeEventListener('resize', handler);
Грамотное использование remove() позволяет избежать
утечек памяти, повторной инициализации контейнеров, накопления
обработчиков событий и деградации производительности в крупных
приложениях, активно использующих Leaflet.