Stats widget

Stats Widget в Deck.gl используется как инструмент наблюдения за производительностью рендеринга, состоянием графического пайплайна и загрузкой GPU/CPU при работе с многослойными визуализациями. Он особенно важен в приложениях, где сцена включает десятки или сотни слоёв, динамические данные, анимации и интерактивные эффекты.

В основе Stats Widget лежит идея прозрачного мониторинга жизненного цикла рендеринга. Каждый кадр в Deck.gl проходит последовательность этапов:

  • подготовка данных (CPU)
  • обновление атрибутов слоёв
  • передача буферов в WebGL
  • отрисовка (GPU)
  • пост-обработка и компоновка

Stats Widget подключается к этому конвейеру и собирает метрики без вмешательства в бизнес-логику приложения.

Ключевой принцип: минимальная инвазивность. Метрики собираются через внутренние hooks Deck.gl и WebGL-контекст, не требуя модификации слоёв.

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

FPS (Frames Per Second)

Одна из базовых метрик — количество кадров в секунду. Она отражает общую плавность визуализации.

  • 60 FPS — целевое значение для плавного интерфейса
  • 30 FPS — допустимый минимум для сложных сцен
  • < 20 FPS — критическая нагрузка

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


Frame Time (время кадра)

t_{frame} = t_{end} - t_{start}

Frame Time показывает, сколько времени занимает полный цикл рендеринга одного кадра.

Разделяется на:

  • CPU time — подготовка данных и логика слоёв
  • GPU time — отрисовка в WebGL
  • idle time — ожидание синхронизации

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


GPU Load

GPU Load отражает насыщенность графического процессора операциями:

  • количество draw calls
  • размер передаваемых буферов
  • сложность шейдеров
  • количество активных слоёв

В Deck.gl один сложный слой может порождать несколько draw calls, особенно при инстансинге.


Number of Layers

Каждый слой в Deck.gl представляет отдельную визуальную сущность: точки, линии, полигоны, текстуры.

Stats Widget отслеживает:

  • общее количество слоёв
  • активные слои (visible)
  • обновляемые слои (dirty state)

Рост количества слоёв влияет не только на GPU, но и на CPU-задачи синхронизации.


Attribute Updates

Deck.gl использует атрибутные буферы для хранения геометрии. Stats Widget фиксирует:

  • частоту пересчёта атрибутов
  • объём обновляемых данных
  • причины обновлений (data change, viewport change, props update)

Особенно критично при streaming-данных, где обновления происходят каждый кадр.


Внутренняя интеграция Stats Widget

Stats Widget подключается к lifecycle Deck.gl через instrumentation API. В React-окружении он часто используется совместно с React, где рендеринг сцены и UI происходят параллельно.

Типовая схема интеграции:

  • DeckGL instance создаётся с включённой instrumentation
  • Stats collector подписывается на события frame start / frame end
  • UI-компонент подписывается на поток метрик

Пример подключения

import {Deck} from '@deck.gl/core';
import {StatsWidget} from '@deck.gl/widgets';

const deck = new Deck({
  initialViewState: {
    longitude: 0,
    latitude: 0,
    zoom: 2
  },
  controller: true,
  layers: []
});

const stats = new StatsWidget(deck);

document.body.appendChild(stats.domElement);

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


Модель обновления данных

Stats Widget работает по push-модели: каждое изменение кадра генерирует новый snapshot состояния.

Структура snapshot обычно включает:

  • timestamp
  • frame duration
  • gpu time estimate
  • draw call count
  • memory usage approximation
  • layer statistics

Система не хранит длинную историю по умолчанию, чтобы минимизировать overhead. Историзация выполняется на уровне приложения при необходимости.


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

Несмотря на то, что Stats Widget является диагностическим инструментом, он сам по себе добавляет нагрузку:

  • дополнительная обработка событий кадра
  • чтение WebGL queries
  • обновление DOM или canvas overlay

Поэтому вводится режимы работы:

Lightweight mode

  • только FPS
  • минимальная частота обновления (1 раз в 500–1000 мс)
  • отсутствие GPU queries

Full instrumentation mode

  • все метрики
  • WebGL timer queries
  • детализация по слоям

WebGL timer queries

Для точного измерения GPU времени Stats Widget использует расширения WebGL:

  • EXT_disjoint_timer_query (WebGL1)
  • EXT_disjoint_timer_query_webgl2 (WebGL2)

Процесс:

  1. отправка запроса таймера перед draw call
  2. выполнение рендеринга на GPU
  3. получение результата после синхронизации

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


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

Каждый слой Deck.gl имеет собственный lifecycle:

  • initialize
  • updateState
  • draw
  • finalize

Stats Widget агрегирует данные по каждому этапу.

Типичные метрики слоя:

  • updateState duration
  • attribute transition time
  • render cost per instance
  • texture binding overhead

Особенно важно при использовании больших инстансированных слоёв (например, ScatterplotLayer с миллионами точек).


Анализ узких мест

Stats Widget позволяет выявлять типичные проблемы:

Частые обновления props

Если props слоёв обновляются слишком часто, происходит:

  • пересоздание буферов
  • повторная загрузка данных
  • лишние re-render циклы

Перегруженные шейдеры

Сложные fragment shaders увеличивают GPU time. Stats Widget фиксирует рост:

  • fragment execution time
  • shader compilation frequency

Excessive draw calls

Каждый draw call — отдельная операция GPU. Рост числа слоёв или отсутствие batching приводит к деградации FPS.


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

Stats Widget может расширяться пользовательскими counters:

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

Это позволяет объединить визуальную производительность и данные приложения в одном dashboard.


Использование в production-режиме

В production Stats Widget часто отключается или переводится в скрытый режим, но сохраняется telemetry API:

  • отправка метрик в backend
  • логирование деградации FPS
  • алерты при падении производительности

Типичная стратегия:

  • development: full mode
  • staging: sampling mode
  • production: telemetry-only

Связь с архитектурой WebGL сцены

Stats Widget фактически отражает состояние WebGL state machine:

  • количество активных buffer objects
  • состояние shader program cache
  • текстурные биндинги
  • depth/stencil state changes

Это позволяет рассматривать Deck.gl не как UI-библиотеку, а как runtime графического движка.


Оптимизация на основе данных Stats Widget

Полученные метрики используются для оптимизации:

  • уменьшение количества слоёв через aggregation
  • применение spatial indexing (quadtree, H3)
  • использование instancing вместо individual geometries
  • кеширование атрибутов
  • throttle обновлений viewport

Каждое изменение подтверждается снижением frame time и стабилизацией FPS.


Ограничения метрик

Stats Widget не всегда отражает полную картину:

  • GPU drivers могут скрывать реальные задержки
  • асинхронность WebGL таймеров
  • влияние браузерного compositing слоя
  • variability между устройствами

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