Отслеживание использования

В Mapbox GL JS встроена система событий, позволяющая отслеживать практически все пользовательские и системные действия: загрузку карты, перемещения, масштабирование, взаимодействие с объектами слоя и изменение состояния источника данных. На базе этой системы строится аналитика использования картографических интерфейсов, измерение производительности и поведенческая статистика.

Mapbox GL JS предоставляет событийную модель, основанную на подписках через map.on(...), что делает возможным детальный контроль над жизненным циклом карты и пользовательскими действиями.


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

map.on('load', () => {
  // карта полностью загружена и готова к работе
});

map.on('render', () => {
  // вызывается при каждой перерисовке кадра
});

map.on('idle', () => {
  // карта завершила все текущие операции и находится в стабильном состоянии
});

Событие load используется как стартовая точка аналитики сессии. Оно фиксирует момент, когда стиль, источники и слои загружены. render применяется для оценки частоты перерисовки и нагрузки на GPU. idle позволяет определить, когда карта перестаёт выполнять активные операции.


Отслеживание пользовательского взаимодействия

Интерактивность карты формирует основной поток аналитических данных. Mapbox GL JS предоставляет события для всех стандартных типов взаимодействия.

Навигация

map.on('move', () => {
  // любое перемещение карты
});

map.on('zoom', () => {
  // изменение масштаба
});

map.on('rotate', () => {
  // поворот карты
});

map.on('pitch', () => {
  // изменение наклона
});

Для аналитики обычно фиксируются не только факт события, но и параметры состояния:

map.on('moveend', () => {
  const center = map.getCenter();
  const zoom = map.getZoom();

  analytics.track('map_move_end', {
    lng: center.lng,
    lat: center.lat,
    zoom
  });
});

Использование moveend, zoomend, rotateend снижает шум данных и позволяет фиксировать только завершённые действия.


Отслеживание взаимодействий с объектами карты

Ключевой слой аналитики связан с кликами и наведением на объекты:

map.on('click', 'cities-layer', (e) => {
  const features = map.queryRenderedFeatures(e.point, {
    layers: ['cities-layer']
  });

  analytics.track('feature_click', {
    layer: 'cities-layer',
    featureCount: features.length
  });
});

События:

  • click — клик по карте или слою
  • mouseenter / mouseleave — наведение курсора
  • dblclick — двойной клик

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


Сбор аналитики через источники данных

Источники (source) в Mapbox GL JS позволяют отслеживать загрузку и обновление геоданных.

map.on('sourcedata', (e) => {
  if (e.isSourceLoaded) {
    analytics.track('source_loaded', {
      sourceId: e.sourceId
    });
  }
});

События источников:

  • sourcedata — любые изменения данных источника
  • data — общий поток обновлений данных
  • styledata — изменение стиля карты

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


Измерение производительности

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

map.on('render', () => {
  const canvas = map.getCanvas();
  const fps = map.getFps?.();

  analytics.track('render_frame', {
    width: canvas.width,
    height: canvas.height,
    fps
  });
});

Дополнительно анализируются:

  • время до первого рендера
  • время полной загрузки стиля
  • задержки при перемещении карты
  • количество перерисовок в секунду

В продвинутых сценариях используется интеграция с PerformanceObserver для измерения WebGL и тайловых операций.


Пользовательские метрики поверх событий карты

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

function trackMapSessionStart() {
  analytics.track('map_session_start', {
    timestamp: Date.now()
  });
}

map.on('load', trackMapSessionStart);

Часто фиксируются следующие метрики:

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

Интеграция с системами аналитики

Mapbox GL JS не ограничивает способ отправки данных. События могут быть связаны с любыми аналитическими платформами.

Пример интеграции с универсальным трекером

function track(eventName, payload) {
  fetch('/analytics', {
    method: 'POST',
    body: JSON.stringify({
      event: eventName,
      payload
    })
  });
}

map.on('zoomend', () => {
  track('zoom_changed', {
    zoom: map.getZoom()
  });
});

Также часто используются очереди событий для уменьшения нагрузки на сеть и батчинга данных.


Контроль объёма и частоты событий

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

Дебаунсинг событий движения

let timeout;

map.on('move', () => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    const center = map.getCenter();
    track('map_idle_position', center);
  }, 300);
});

Ограничение частоты рендера

let lastTime = 0;

map.on('render', () => {
  const now = performance.now();
  if (now - lastTime < 1000) return;

  lastTime = now;
  track('render_snapshot', {
    fps: map.getFps?.()
  });
});

Управление телеметрией библиотеки

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

В зависимости от конфигурации проекта возможно отключение встроенной телеметрии через параметры инициализации или глобальные настройки библиотеки.

// пример конфигурационного отключения (зависит от версии SDK)
mapboxgl.config = {
  TELEMETRY_COLLECTION: false
};

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


Анализ пользовательских сценариев

Собранные события позволяют реконструировать типовые сценарии использования:

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

На основе этих данных строятся тепловые карты поведения и оптимизируется UX интерфейса карты.


Логирование ошибок и нестандартных состояний

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

map.on('error', (e) => {
  analytics.track('map_error', {
    message: e.error?.message,
    source: e.sourceId
  });
});

Это позволяет фиксировать:

  • недоступные тайлы
  • ошибки стиля
  • проблемы WebGL контекста
  • сбои источников данных

Структурирование событийного слоя

В крупных приложениях вводится единый слой абстракции над событиями карты:

class MapAnalytics {
  constructor(map, tracker) {
    this.map = map;
    this.tracker = tracker;

    this.init();
  }

  init() {
    this.map.on('moveend', this.trackMoveEnd.bind(this));
    this.map.on('click', this.trackClick.bind(this));
  }

  trackMoveEnd() {
    this.tracker('map_move_end', {
      center: this.map.getCenter(),
      zoom: this.map.getZoom()
    });
  }

  trackClick(e) {
    this.tracker('map_click', {
      point: e.point
    });
  }
}

Такая архитектура отделяет логику аналитики от логики рендеринга карты и упрощает масштабирование системы отслеживания.