Жизненный цикл компонентов

Жизненный цикл компонентов в OpenLayers строится вокруг модели наблюдаемых объектов, событийной системы и строгого управления ресурсами, где каждый элемент карты проходит стадии создания, привязки, обновления, перерисовки и уничтожения. Архитектура библиотеки опирается на базовые классы ol/Observable, ol/Object, ol/Disposable, обеспечивающие единообразное поведение всех компонентов.

Каждый компонент OpenLayers можно рассматривать как объект с тремя ключевыми состояниями:

  • инициализация и конфигурация;
  • активная работа внутри карты;
  • деактивация и освобождение ресурсов.

Основная особенность заключается в том, что большинство объектов не существуют изолированно — они привязаны к карте (Map) или к другим контейнерам (например, Layer к Map, Source к Layer).

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

Создание объектов и начальная инициализация

Создание компонентов включает конструирование экземпляра и установку начальных свойств через set() или параметры конструктора.

Ключевой механизм инициализации:

  • установка свойств через observable-систему;
  • регистрация внутренних слушателей;
  • подготовка к первому рендеру.

Большинство классов наследуют поведение ol/Object, где изменение свойств вызывает событие change.

Пример внутренней логики:

  • создание View инициирует наблюдение за центром, масштабом и проекцией;
  • Layer регистрирует связь с источником данных;
  • Source подготавливает загрузочные механизмы.

Привязка к карте и DOM-узлу

Ключевым этапом жизненного цикла является привязка карты к DOM-элементу через setTarget().

В этот момент происходит:

  • создание контейнеров для рендеринга;
  • инициализация canvas/WebGL контекста;
  • запуск цикла отрисовки;
  • привязка обработчиков событий мыши и клавиатуры.

Разрыв связи с DOM выполняется вызовом:

map.setTarget(null);

Это приводит к остановке рендеринга и освобождению графического контекста, но не обязательно уничтожает все дочерние объекты.

Реактивная система изменений

OpenLayers использует событийную модель, где каждый значимый объект является наблюдаемым.

Основные механизмы:

  • set(key, value) — изменение состояния;
  • get(key) — получение значения;
  • событие change — уведомление о модификации;
  • специализированные события (change:resolution, change:center и т.д.).

Изменение параметров View приводит к цепочке обновлений:

  • пересчёт матрицы преобразования координат;
  • обновление тайловых источников;
  • пометка слоя как требующего перерисовки.

Важный аспект — каскадность обновлений: изменение одного свойства может инициировать обновление всей сцены.

Цикл рендеринга карты

Рендеринг в OpenLayers организован как непрерывный цикл, управляемый внутренним планировщиком.

Основные стадии:

prerender

Стадия подготовки, на которой:

  • вычисляются новые трансформации;
  • обновляются состояния слоёв;
  • подготавливаются tile requests;
  • формируется список видимых объектов.

render

Основной этап отрисовки:

  • вычисление матриц отображения;
  • отрисовка слоёв в порядке z-index;
  • применение стилей;
  • обработка векторных геометрий.

postrender

Завершающий этап:

  • очистка временных структур;
  • фиксация состояния кадра;
  • подготовка к следующему циклу;
  • генерация событий завершения рендеринга.

Рендер-цикл активируется не непрерывно, а по необходимости — при изменении состояния карты или данных источников.

Жизненный цикл слоя

Слой (Layer) проходит следующие этапы:

  1. создание экземпляра;
  2. привязка к источнику (Source);
  3. добавление в карту;
  4. участие в рендеринге;
  5. удаление из карты;
  6. освобождение ресурсов.

При добавлении слоя в карту происходит регистрация:

  • подписки на изменения источника;
  • слушателей изменения видимости;
  • привязки к системе отрисовки.

При удалении слоя:

map.removeLayer(layer);

выполняется:

  • остановка загрузки данных;
  • снятие подписок на события;
  • удаление из списка рендеринга.

Жизненный цикл источников данных

Источники (Source) отвечают за загрузку и хранение геоданных.

Особенности жизненного цикла:

  • ленивое создание запросов данных;
  • кэширование тайлов и объектов;
  • асинхронная загрузка.

Типичный сценарий:

  • создание источника;
  • привязка к слою;
  • триггер загрузки при первом отображении;
  • обновление при изменении параметров проекции или масштаба;
  • очистка кэша при уничтожении слоя.

Удаление источника происходит косвенно через слой или вручную через clear() и прекращение подписок.

Жизненный цикл взаимодействий и контролов

Interaction и Control являются компонентами верхнего уровня, подключаемыми к карте.

При добавлении:

  • регистрируются обработчики событий pointer/keyboard;
  • добавляются слушатели изменения состояния карты;
  • включается логика взаимодействия с геометрией.

При удалении:

map.removeInteraction(interaction);
map.removeControl(control);

происходит:

  • снятие обработчиков событий;
  • очистка внутренних состояний;
  • прекращение влияния на карту.

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

Система событий основана на ключах подписок.

Каждое подписанное событие возвращает идентификатор:

const key = layer.on('change', handler);

Удаление подписки:

import { unByKey } from 'ol/Observable';
unByKey(key);

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

Уничтожение и освобождение ресурсов

Механизм dispose() реализован не во всех объектах одинаково, но общая концепция включает:

  • остановку асинхронных процессов;
  • удаление слушателей;
  • очистку ссылок на DOM и WebGL контекст;
  • освобождение кэшей.

Типичный сценарий завершения жизненного цикла карты:

map.setTarget(null);
map.getLayers().clear();
map = null;

Дополнительно могут потребоваться явные вызовы очистки источников и подписок.

Внутренние зависимости и каскадность уничтожения

Жизненный цикл компонентов связан иерархически:

  • Map управляет слоями и взаимодействиями;
  • Layer управляет источником;
  • Source управляет загрузчиками;
  • View управляет матрицей отображения.

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

Каскадное поведение зависит от конкретной реализации и способа подключения компонентов.

Особенности повторного использования компонентов

Компоненты OpenLayers могут повторно использоваться при повторной привязке:

  • повторный вызов setTarget();
  • перенос слоёв между картами;
  • переинициализация источников.

При этом сохраняется состояние объекта, включая подписки и внутренние кэши, что влияет на поведение при повторной активации.

Синхронизация состояния и отложенные обновления

Система обновлений оптимизирована через батчинг:

  • несколько set() объединяются в один цикл рендеринга;
  • обновления откладываются до следующего кадра;
  • события агрегируются для минимизации перерасчётов.

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