Управление жизненным циклом

Жизненный цикл карты в HERE Technologies в JavaScript определяется последовательностью создания, конфигурации, активного использования и корректного освобождения ресурсов. Ошибки на любом из этих этапов приводят к утечкам памяти, деградации производительности и нестабильности WebGL-контекста, особенно в SPA-приложениях и при частой маршрутизации между страницами.

Создание карты начинается с подготовки платформы и слоёв. Базовый объект платформы выступает точкой доступа ко всем сервисам: тайлам, геокодированию, маршрутизации.

const platform = new H.service.Platform({
  apikey: 'YOUR_API_KEY'
});

const defaultLayers = platform.createDefaultLayers();

const map = new H.Map(
  document.getElementById('map'),
  defaultLayers.vector.normal.map,
  {
    zoom: 10,
    center: { lat: 52.5, lng: 13.4 },
    pixelRatio: window.devicePixelRatio || 1
  }
);

На этом этапе создаются ключевые внутренние структуры:

  • WebGL или Canvas рендерер
  • контейнер событий
  • менеджер тайлов
  • слой взаимодействия с UI

Карта начинает занимать ресурсы сразу после привязки к DOM-элементу.

Подключение поведенческого слоя

Интерактивность карты обеспечивается объектом поведения. Он отвечает за зум, панорамирование, инерцию и обработку пользовательских событий.

const beh * avior = new H.mapevents.Behavior(
  new H.mapevents.MapEvents(map)
);

Поведенческий слой создаёт дополнительный набор слушателей DOM и внутренних событий карты. Эти обработчики должны быть учтены при последующей очистке, поскольку они не удаляются автоматически при удалении DOM-контейнера.

Система UI-компонентов

Интерфейсные элементы подключаются отдельно и также участвуют в жизненном цикле:

const ui = H.ui.UI.createDefault(map, defaultLayers);

UI-компоненты создают:

  • кнопки масштабирования
  • элементы управления слоями
  • информационные баллоны (bubbles)
  • системные панели

Каждый из этих элементов хранит ссылки на карту и её события, что увеличивает важность корректного уничтожения UI при выгрузке карты.

Обновление состояния карты

В активной фазе жизненного цикла карта подвергается постоянным изменениям: перемещение центра, изменение масштаба, добавление объектов.

Изменение состояния выполняется через методы:

map.setCenter({ lat: 48.85, lng: 2.35 });
map.setZoom(12);

Добавление объектов:

const marker = new H.map.Marker({ lat: 48.85, lng: 2.35 });
map.addObject(marker);

Каждый добавленный объект становится частью внутреннего графа сцены. При большом количестве объектов формируется дерево, требующее явной очистки при завершении работы.

Управление слоями и объектами

Объекты карты не удаляются автоматически при смене состояния интерфейса приложения. Их жизненный цикл контролируется вручную.

Удаление отдельных объектов:

map.removeObject(marker);

Удаление групп объектов:

map.removeObjects(map.getObjects());

Слои также могут динамически добавляться и удаляться:

map.addLayer(customLayer);
map.removeLayer(customLayer);

Каждый слой может содержать собственные тайлы и рендер-ресурсы, что увеличивает нагрузку на память при накоплении неиспользуемых слоёв.

Управление событиями

Система событий в HERE Maps построена на подписках. Любая подписка создаёт ссылку, которая должна быть разрушена вручную.

const listener = map.addEventListener('tap', function (evt) {
  console.log(evt.target);
});

Удаление слушателя:

H.mapevents.EventTarget.removeListener(listener);

Игнорирование удаления слушателей приводит к накоплению «висячих» обработчиков, продолжающих реагировать на события даже после уничтожения карты.

Особенности WebGL-контекста

При использовании векторных слоёв карта использует WebGL. Этот контекст ограничен браузером: одновременно может существовать ограниченное число активных контекстов.

При повторной инициализации карты без очистки старого экземпляра возникают ошибки:

  • потеря рендеринга
  • сбой создания контекста
  • черный экран вместо карты

Контекст освобождается только при полном уничтожении экземпляра карты и связанных сервисов.

Корректное уничтожение карты

Завершающая стадия жизненного цикла включает последовательное освобождение всех ресурсов.

map.dispose();

В зависимости от версии API и сборки также применяется ручная очистка зависимостей:

behavior.disable();
map.removeObjects(map.getObjects());
map.getViewPort().dispose && map.getViewPort().dispose();

UI-слой требует отдельного удаления:

ui.dispose();

Платформа как провайдер сервисов обычно не уничтожается при смене карты, но в изолированных приложениях может быть очищена косвенно через удаление ссылок.

Жизненный цикл в SPA-приложениях

В одностраничных приложениях карта часто создаётся при входе на маршрут и уничтожается при выходе. Неправильная реализация приводит к накоплению скрытых экземпляров.

Типичная структура жизненного цикла:

  • создание контейнера
  • инициализация Platform
  • создание Map
  • подключение Behavior и UI
  • регистрация событий
  • работа с объектами и слоями
  • очистка событий
  • удаление объектов и слоёв
  • уничтожение UI
  • dispose карты

Особое значение имеет порядок уничтожения: сначала удаляются слушатели и объекты, затем UI, и только после этого сама карта.

Управление повторной инициализацией

При повторном создании карты в одном контейнере требуется гарантировать полную очистку DOM-связанных ресурсов.

container.innerHTML = '';

Однако очистка DOM недостаточна без вызова методов уничтожения API-объектов. В противном случае WebGL-контекст продолжает существовать в памяти браузера.

Утечки памяти и их причины

Наиболее частые источники утечек:

  • неотписанные события addEventListener
  • сохранённые ссылки на map в замыканиях
  • не удалённые маркеры и полилинии
  • повторная инициализация без dispose
  • активные таймеры, связанные с обновлением карты

Каждый из этих факторов увеличивает потребление памяти даже после удаления визуального компонента.

Поведение при скрытии контейнера

Скрытие карты через CSS (display: none) не останавливает её работу. Тайлы продолжают загружаться, события обрабатываются, WebGL-контекст остаётся активным.

Для приостановки требуется явное отключение поведения:

behavior.disable();

И временная остановка рендеринга через логическое управление состоянием приложения.

Управление ресурсами в долгоживущих приложениях

В приложениях с длительным временем работы карты применяется стратегия частичного переиспользования:

  • повторное использование Platform
  • пересоздание только Map
  • ограничение числа активных слоёв
  • регулярная очистка объектов
  • контроль подписок через централизованный менеджер событий

Такая архитектура снижает нагрузку на память и предотвращает деградацию производительности при длительной работе интерфейса.