Performance monitoring

Архитектура производительности и ключевые точки измерения

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

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

  • частота кадров и стабильность рендеринга;
  • количество и скорость загрузки тайлов 3D Tiles;
  • использование GPU и CPU;
  • сетевые запросы и их очередь;
  • потребление памяти (JS heap, WebGL buffers);
  • время подготовки сцены (scene update / render loop).

CesiumJS строится вокруг непрерывного цикла Scene, поэтому любые задержки в одном из слоёв немедленно отражаются на итоговом FPS.


Измерение FPS и кадрового времени

Базовая метрика — частота кадров. В CesiumJS встроен механизм отображения FPS через сцену:

viewer.scene.debugShowFramesPerSecond = true;

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

Более детализированное измерение включает разбиение времени кадра:

  • время обновления сцены (update);
  • время рендеринга (render);
  • время подготовки команд WebGL.

Для глубокой диагностики используется performance.now():

const start = performance.now();

viewer.render();

const end = performance.now();
console.log("Frame time:", end - start);

В высоконагруженных сценах с 3D Tiles важно учитывать не только среднее значение, но и 95-й перцентиль времени кадра, так как именно он определяет ощущаемую плавность.


Мониторинг 3D Tiles и потоковой загрузки

Подсистема 3D Tiles является основным источником вариативности производительности. Объекты Cesium3DTileset предоставляют встроенные статистики:

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

viewer.scene.primitives.add(tileset);

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

Ключевые метрики:

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

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

viewer.scene.primitives.addEventListener("tileFailed", function(error) {
    console.log(error);
});

Увеличение количества активных тайлов напрямую влияет на GPU fill rate и память текстур.


Планировщик запросов и сетевые ограничения

CesiumJS использует внутренний RequestScheduler, который управляет параллелизмом сетевых запросов.

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

  • лимит одновременных запросов;
  • приоритеты (render vs preload);
  • очередь ожидания тайлов.

Наблюдение за сетевой активностью позволяет выявлять узкие места:

viewer.scene.requestRenderMode = true;
viewer.scene.maximumRenderTimeChange = 0;

При включении request-based режима можно фиксировать моменты, когда рендер инициируется исключительно загрузкой данных.


Инструменты Scene Debug и визуальные индикаторы

CesiumJS содержит набор встроенных debug-инструментов:

viewer.scene.debugShowCommands = true;
viewer.scene.debugShowFrustums = true;
viewer.scene.debugShowFramesPerSecond = true;
viewer.scene.debugShowDepthFrustum = true;

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

  • количество WebGL draw calls;
  • распределение камерных фрустумов;
  • эффективность отсечения (culling);
  • нагрузку на рендер pipeline.

Дополнительно важен инструмент:

viewer.scene.globe.showWireframe = true;

Он помогает выявлять избыточную геометрию и проблемы с LOD.


GPU и WebGL-профилирование

Производительность GPU напрямую связана с количеством draw calls и размером буферов. В WebGL-контексте CesiumJS это выражается в следующих параметрах:

  • количество активных буферов вершин;
  • количество текстур в памяти;
  • размер framebuffer;
  • переключения состояний (state changes).

Для мониторинга WebGL используется браузерный Performance Panel, однако Cesium добавляет дополнительные индикаторы через статистику сцены:

console.log(viewer.scene.frameState);

Внутри frameState содержится информация:

  • количество отрисованных примитивов;
  • состояние frustum culling;
  • активные command list.

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

Более точная диагностика достигается через стандартный Performance API:

performance.mark("cesium-start");

viewer.render();

performance.mark("cesium-end");
performance.measure("cesium-frame", "cesium-start", "cesium-end");

console.log(performance.getEntriesByName("cesium-frame"));

Это позволяет интегрировать CesiumJS в системные профилировщики Chrome DevTools и фиксировать регрессии между сборками.


Метрики памяти и утечки

CesiumJS активно использует WebGL ресурсы, которые не всегда отражаются в JS heap.

Основные зоны контроля:

  • геометрические буферы (VertexArray);
  • текстуры (особенно тайловые карты);
  • кэши декодированных моделей;
  • ресурсы imagery layers.

Мониторинг JS памяти:

console.log(performance.memory);

Рост usedJSHeapSize при стабильной сцене указывает на утечки в кэшировании тайлов или повторном создании сущностей.


Производительность слоёв изображения и terrain

Imagery layers и terrain влияют на ранний этап рендеринга сцены. Их загрузка конкурирует за сетевые ресурсы с 3D Tiles.

Метрики:

  • время загрузки тайлов изображений;
  • количество активных imagery layers;
  • приоритет слоёв;
  • разрешение текстур.

Оптимизационные признаки:

  • переизбыточные high-resolution tiles;
  • отсутствие tile discard policy;
  • чрезмерное количество overlay слоёв.

Frame State и анализ pipeline

frameState является центральной структурой диагностики:

viewer.scene.preRender.addEventListener(function(scene, time) {
    const state = scene.frameState;
    console.log(state.commandList.length);
});

Ключевые параметры:

  • commandList — набор draw calls;
  • cullingVolume — активные ограничения видимости;
  • passes — стадии рендеринга;
  • tilesToRender — активные 3D Tiles.

Рост commandList напрямую коррелирует с падением FPS.


Стабилизация производительности через requestRenderMode

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

viewer.scene.requestRenderMode = true;
viewer.scene.maximumRenderTimeChange = Infinity;

В этом режиме кадры отрисовываются только при изменении состояния сцены:

  • перемещение камеры;
  • загрузка тайлов;
  • изменение сущностей.

Метрики качества кадра и дрожание (jank)

Помимо FPS важен анализ стабильности времени кадра:

  • стабильный 16ms кадр при 60 FPS;
  • скачки 16–50ms указывают на загрузку тайлов;
  • пики выше 100ms вызывают визуальные лаги.

Анализ jitter выполняется через распределение frame time:

const frameTimes = [];
viewer.scene.postRender.addEventListener(function() {
    const now = performance.now();
    frameTimes.push(now);
});

Интеграция с внешними профайлерами

CesiumJS хорошо совместим с Chrome DevTools Performance tab:

  • recording timeline;
  • анализ scripting/rendering blocks;
  • GPU rasterization pipeline;
  • long tasks detection.

Особенно важны long tasks (>50ms), которые блокируют render loop.


Балансировка нагрузки в сложных сценах

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

  • снижение screen space error у 3D Tiles;
  • уменьшение texture resolution;
  • отключение неактивных layers;
  • ограничение cache size.

Пример управления LOD:

tileset.maximumScreenSpaceError = 8;

Меньшее значение увеличивает качество, но снижает производительность.


Статистика сцены и агрегированные метрики

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

  • FPS average / min / max;
  • draw calls per frame;
  • active tiles count;
  • GPU memory estimate;
  • network request rate.

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