Профилирование

Инструменты профилирования в CesiumJS опираются на сочетание встроенных средств движка, возможностей браузера и анализа структуры сцены. Производительность в WebGL-приложениях определяется не только JavaScript-логикой, но и состоянием графического конвейера, количеством отрисовываемых примитивов, особенностями тайловой подгрузки и частотой перерасчёта сцены.

Первый уровень анализа производительности связан с кадрами и временем отрисовки. В CesiumJS ключевым объектом является Viewer, внутри которого работает Scene. Базовые метрики извлекаются через встроенные свойства:

  • количество кадров в секунду (FPS)
  • время одного кадра (frame time)
  • время обработки сцены (update time)
  • время рендеринга (render time)
  • количество отрисованных команд WebGL

Часто используется визуальный вывод FPS:

viewer.scene.debugShowFramesPerSecond = true;

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

Однако FPS является поверхностной метрикой. Для глубокого анализа необходимо разделение этапов кадра: CPU update, culling, issuing draw calls, GPU execution.

Профилирование JavaScript-части

Основная логика CesiumJS выполняется на CPU в рамках цикла requestAnimationFrame. Узкие места часто возникают не в WebGL, а в JavaScript-слое:

  • обновление сущностей (Entity)
  • пересчёт матриц камеры
  • обработка событий ввода
  • обновление тайлсетов и геометрии
  • работа с датами и временем в астрономических сценах

Профилирование выполняется через Chrome DevTools Performance Panel. Запись профиля кадра позволяет увидеть распределение времени:

  • Scripting
  • Rendering
  • Painting
  • System

Особое внимание уделяется длинным задачам (Long Tasks), которые блокируют кадр. В CesiumJS типичным источником таких задач является пересчёт геометрии и LOD-структур.

Оптимизация JavaScript-слоя включает:

  • снижение частоты обновления сущностей
  • отказ от массовых Entity в пользу Primitive
  • кэширование вычислений матриц
  • минимизация аллокаций в каждом кадре

Режим рендеринга и управление циклом кадров

CesiumJS поддерживает ленивый рендеринг, который существенно влияет на нагрузку CPU и GPU.

Ключевая настройка:

viewer.scene.requestRenderMode = true;

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

viewer.scene.requestRender();

Дополнительный параметр:

viewer.scene.maximumRenderTimeChange = Infinity;

Он управляет чувствительностью к изменениям времени и анимации.

Профилирование показывает, что переход в requestRenderMode часто уменьшает FPS-зависимые расходы, но увеличивает важность точного управления состоянием сцены.

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

Основная нагрузка в CesiumJS часто переносится на GPU. В WebGL конвейере ключевыми ограничениями являются:

  • количество draw calls
  • размер и количество буферов вершин
  • переключения shader programs
  • загрузка текстур
  • fill rate (заполнение пикселей)

Chrome DevTools предоставляет вкладку Performance → GPU, а также инструмент WebGL Insights (внешние расширения и отладчики).

Типичные проблемы GPU:

  • чрезмерное количество материалов в Cesium3DTileset
  • большие текстуры без mipmapping
  • отсутствие компрессии текстур (WebP, KTX2)
  • перегруженные fragment shaders (атмосферные эффекты, туман, bloom)

CesiumJS активно использует батчинг геометрии, но эффективность зависит от структуры данных. Разбиение сцены на множество мелких сущностей резко увеличивает draw calls.

Tilesets и их влияние на производительность

3D Tiles являются центральной структурой данных CesiumJS. Производительность сильно зависит от:

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

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

  • maximumScreenSpaceError
  • skipLevelOfDetail
  • loadSiblings
  • dynamicScreenSpaceError

Увеличение maximumScreenSpaceError снижает детализацию, но уменьшает количество загружаемых тайлов и draw calls.

Пример настройки:

tileset.maximumScreenSpaceError = 16;
tileset.dynamicScreenSpaceError = true;

Профилирование tilesets включает анализ:

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

CesiumJS предоставляет внутренние debug-метрики через Cesium3DTilesInspector:

  • количество tiles in memory
  • number of requests
  • cache hit ratio

Память и утечки

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

  • накоплением неуничтоженных Entity
  • утечками подписок на события (Event)
  • неочищенными DataSource
  • кешированием текстур и геометрии

Chrome DevTools Memory Panel позволяет отслеживать:

  • heap snapshot
  • allocation timeline
  • detached DOM trees

Особенно критичны сценарии, где сцена часто пересоздаётся без вызова destroy():

viewer.destroy();

CesiumJS использует собственную систему ресурсов WebGL, поэтому утечки часто проявляются как рост GPU memory, который не всегда виден в JS heap.

Инструменты Cesium для диагностики сцены

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

viewer.scene.debugShowFramesPerSecond = true;
viewer.scene.debugShowCommands = true;
viewer.scene.debugWireframe = true;

Также используется CesiumInspector:

  • визуализация draw calls
  • отображение тайлов
  • анализ производительности primitives
  • просмотр bounding volumes

Wireframe режим особенно полезен для выявления избыточной геометрии и перекрытий.

Culling и геометрическая оптимизация

Одним из ключевых этапов оптимизации является отсечение невидимых объектов:

  • frustum culling
  • occlusion culling
  • horizon culling

CesiumJS использует bounding volumes:

  • bounding sphere
  • oriented bounding box (OBB)
  • axis-aligned bounding box (AABB)

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

Оптимизация включает:

  • корректную генерацию 3D Tiles
  • уменьшение перекрывающихся геометрий
  • настройку bounding volume hierarchy

Загрузка ресурсов и сетевые узкие места

Производительность часто ограничивается не рендерингом, а сетью:

  • медленная загрузка terrain tiles
  • большие batched 3D models
  • отсутствие CDN оптимизации

DevTools Network Panel позволяет анализировать:

  • waterfall загрузки tiles
  • latency запросов
  • размер payload

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

Оптимизация сцен и стратегий рендера

Профилирование сцены обычно приводит к следующим оптимизационным стратегиям:

  • переход от Entity к Primitive
  • уменьшение количества одновременно активных тайлов
  • снижение частоты обновления датчиков и анимации
  • использование instancing для повторяющихся объектов
  • отключение постобработки (bloom, SSAO)

Особенно затратными являются эффекты постобработки:

  • ambient occlusion
  • depth of field
  • bloom
  • FXAA

Их отключение часто даёт значительный прирост FPS на слабых GPU.

Тайминг кадра и анализ pipeline

Глубокое профилирование требует анализа каждого этапа кадра:

  1. Input handling
  2. Scene update
  3. Culling
  4. Command generation
  5. WebGL draw calls
  6. GPU execution

CesiumJS позволяет косвенно измерять эти этапы через PerformanceDisplay и internal timers.

Наиболее критическим показателем является разница между CPU frame time и GPU frame time. Если CPU выше — проблема в JavaScript и сцене. Если GPU выше — проблема в рендеринге, шейдерах или геометрии.

Стабилизация частоты кадров

Для стабилизации рендера используется ограничение частоты:

viewer.targetFrameRate = 30;

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

Альтернативный подход — адаптивный рендеринг, при котором сцена динамически снижает детализацию при росте нагрузки GPU.

Анализ поведения камеры

Камера в CesiumJS напрямую влияет на производительность, так как определяет:

  • количество видимых тайлов
  • уровень детализации terrain
  • количество пересекаемых bounding volumes

Профилирование показывает, что резкие перемещения камеры вызывают пики загрузки CPU и сети из-за пересчёта LOD.

Оптимизация включает:

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

Кэширование и повторное использование ресурсов

CesiumJS активно использует кэш:

  • geometry cache
  • texture cache
  • tile cache

Неэффективное использование кэша приводит к постоянной перезагрузке ресурсов. Профилирование позволяет выявить низкий cache hit ratio, что указывает на неправильные настройки tileset или слишком агрессивное освобождение памяти.

Контроль кэша особенно важен при работе с большими 3D Tiles сценами и динамическими данными.