Мониторинг производительности

Ключевые аспекты производительности

В CesiumJS производительность определяется совокупностью факторов, связанных с рендерингом сцены, загрузкой данных и работой WebGL. Основные метрики, требующие контроля:

  • частота кадров (FPS)
  • время отрисовки кадра (frame time)
  • загрузка тайлов 3D Tiles
  • использование памяти (GPU/CPU)
  • количество draw calls
  • время выполнения update/render pipeline

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


Встроенные инструменты диагностики CesiumJS

CesiumJS предоставляет набор встроенных механизмов, позволяющих отслеживать состояние сцены без внешних профайлеров.

Scene.debugShowFramesPerSecond

Одним из базовых инструментов является отображение FPS прямо на сцене:

viewer.scene.debugShowFramesPerSecond = true;

Этот режим визуализирует текущую частоту кадров и даёт первичное представление о стабильности рендеринга. Падение FPS часто связано с перегрузкой GPU или чрезмерным количеством объектов в сцене.


Performance Overlay через Scene

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

viewer.scene.debugShowFrameInfo = true;
viewer.scene.debugShowFrustumPlanes = true;
viewer.scene.debugShowCommands = true;

Эти режимы помогают анализировать:

  • количество команд отрисовки
  • состояние фрустума камеры
  • распределение объектов по кадру

Анализ 3D Tiles и загрузки данных

Работа с 3D Tiles является одной из наиболее ресурсоёмких операций в CesiumJS. Контроль производительности здесь опирается на статистику тайлсетов.

Cesium3DTileset statistics

const tileset = new Cesium.Cesium3DTileset({
    url: 'tileset.json'
});

viewer.scene.primitives.add(tileset);

tileset.debugShowStatistics = true;

Статистика включает:

  • количество загруженных тайлов
  • количество видимых тайлов
  • число выброшенных из памяти узлов
  • уровень детализации (LOD)

Рост числа активных тайлов напрямую влияет на FPS и потребление памяти.


События загрузки тайлов

CesiumJS предоставляет события для отслеживания состояния загрузки:

tileset.tileLoad.addEventListener(function(tile) {
    console.log('Tile loaded:', tile);
});

tileset.tileUnload.addEventListener(function(tile) {
    console.log('Tile unloaded:', tile);
});

Эти события позволяют выявить:

  • перегрузку сети
  • избыточный уровень детализации
  • неоптимальные bounding volume настройки

Контроль цикла рендеринга

CesiumJS использует собственный render loop, который может работать в режиме постоянной отрисовки или по запросу.

requestRenderMode

const viewer = new Cesium.Viewer('cesiumContainer', {
    requestRenderMode: true,
    maximumRenderTimeChange: Infinity
});

В этом режиме сцена перерисовывается только при изменениях. Это существенно снижает нагрузку на CPU и GPU в статичных сценах.

Ключевые моменты:

  • снижение энергопотребления
  • уменьшение количества draw calls
  • зависимость от явных событий изменения сцены

requestRender

viewer.scene.requestRender();

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


Использование Performance API

Для глубокой диагностики применяется стандартный Web Performance API.

performance.mark('cesium-frame-start');

viewer.scene.preRender.addEventListener(function() {
    performance.mark('cesium-frame-end');
    performance.measure('cesium-frame', 'cesium-frame-start', 'cesium-frame-end');
});

Данный подход позволяет:

  • измерять полный цикл кадра
  • анализировать пики нагрузки
  • выявлять узкие места в pipeline

Анализ WebGL нагрузки

CesiumJS работает поверх WebGL, поэтому значительная часть проблем связана с GPU.

Ключевые показатели:

  • количество активных текстур
  • размер буферов вершин
  • число shader program switches
  • draw calls per frame

Chrome DevTools (Performance + WebGL Inspector) позволяет выявлять:

  • перегрузку видеопамяти
  • частые переключения контекста
  • неэффективные шейдеры

Профилирование сцены

CesiumJS предоставляет возможности анализа сцены через инспектор:

viewer.extend(Cesium.viewerCesiumInspectorMixin);

Инспектор позволяет отслеживать:

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

Это особенно важно при работе с крупными сценами и 3D Tiles.


Оптимизация через уровень детализации (LOD)

LOD напрямую влияет на производительность. CesiumJS автоматически управляет уровнем детализации, однако его поведение можно контролировать.

Основные параметры:

const tileset = new Cesium.Cesium3DTileset({
    maximumScreenSpaceError: 16,
    dynamicScreenSpaceError: true
});
  • maximumScreenSpaceError — баланс между качеством и скоростью
  • dynamicScreenSpaceError — адаптивное управление детализацией

Снижение детализации уменьшает:

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

Контроль памяти

Память в CesiumJS распределяется между CPU и GPU. Основные источники утечек:

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

Мониторинг возможен через:

console.log(viewer.scene.primitives.length);
console.log(viewer.scene.globe._surface.tileProvider);

Также важен контроль:

  • количества активных текстур
  • кеша imagery providers
  • геометрических буферов

Сетевые аспекты загрузки данных

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

Основные метрики:

  • время загрузки tileset.json
  • latency запросов текстур
  • параллельность HTTP-запросов

Оптимизация достигается через:

  • CDN для тайлов
  • сжатие draco/gzip
  • уменьшение количества HTTP-запросов
  • батчинг геометрии

Динамическая адаптация производительности

CesiumJS поддерживает автоматическую адаптацию нагрузки через параметры сцены:

viewer.scene.maximumRenderTimeChange = 0.0;
viewer.scene.fog.enabled = true;
viewer.scene.globe.maximumScreenSpaceError = 2;

Эти настройки позволяют:

  • снижать детализацию при нагрузке
  • уменьшать дальность прорисовки
  • ограничивать сложность сцены

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

При работе с кастомными сущностями важно учитывать время их обновления:

viewer.clock.onTick.addEventListener(function(clock) {
    // логика обновления объектов
});

Проблемные участки обычно возникают при:

  • массовом обновлении entities
  • частых пересчётах координат
  • синхронизации с внешними потоками данных

Контроль частоты обновлений сущностей

Оптимизация достигается через снижение частоты изменений:

  • группировка обновлений
  • throttling событий
  • использование immutable данных

Профилирование на уровне кадрового цикла

CesiumJS разделяет рендеринг на этапы:

  • update
  • resolve frame state
  • render
  • post-process

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

viewer.scene.preUpdate.addEventListener(() => {});
viewer.scene.postRender.addEventListener(() => {});

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

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