Files
Glint-Runtime/docs/ru/architecture/02-performance.md

3.6 KiB
Raw Permalink Blame History

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

Измерения с флагом --perf на desktop.glbc.

Результаты замеров

Steady state (нет событий, idle):

VDOM: 6.6ms | Style: 0.3ms | Render: 7.2ms | Total: 14.1ms

При событиях (перетаскивание слайдера, пиковые значения):

VDOM: 17.4ms | Style: 0.8ms | Render: 15.2ms | Total: 33.5ms ⚠️

60 FPS frame budget: 16ms. В покое укладываемся (14ms), при событиях — нет (до 33ms).

Анализ bottleneck'ов

Style matching — НЕ bottleneck (0.3-0.8ms)

Style matching занимает менее 1ms даже на пике. Это результат работы:

  • Phase 4 (StyleIndex) — O(K) вместо O(N×M)
  • Phase 8 (StyleCache) — мемоизация computed style

VDOM eval — основной потребитель (6-17ms)

В покое ~6.6ms — это полный проход по дереву Element'ов. При событиях до 17ms:

  • evaluate_vdom_incr пересчитывает dirty-элементы (Phase 3)
  • Каждое событие может делать dirty целые поддеревья
  • Внутри: resolve_string, resolve_prop, compute_cached, рекурсивный проход

Render — второй потребитель (7-15ms)

Здесь главный резерв оптимизации. render_element создаёт ВСЕ Iced-виджеты каждый кадр с нуля, даже если Element не изменился. Iced затем диффит новое дерево со старым — но само построение дерева стоит ~7ms.

Сценарий: слайдер

  1. SliderChangedage и volume_level меняются
  2. tracker.on_variable_changed → dirty_set для зависимых элементов
  3. evaluate_vdom_incr пересчитывает dirty-элементы и их детей
  4. view()render_element для ВСЕХ элементов (полный перерендер)
  5. Итог: VDOM 13ms + Render 14ms = 27ms — пропуск кадра

Первые несколько кадров после события — самые тяжёлые (VDOM ~13ms), затем стабилизируются (~7ms), так как dirty_set постепенно очищается.

Рекомендации

  1. Phase 9.3 — кэш виджетов — сократит Render с 7ms до ~0ms для неизменившихся элементов. Если изменился 1 элемент из 50, перерендеривать нужно только его. Это снизит общее время с 14ms до ~7ms в покое.

  2. Phase 1 — Value enum в стиляхComputedStyle::compute() и parse_*() принимают &str и парсят каждое свойство. Если передавать &Value — парсинг не нужен. Потенциально ускорит и style matching, и VDOM eval.

  3. Phase 2 — InternedStr — сравнения строк (type_name == "Button", key == "padding-top") происходят тысячами за кадр. Замена на сравнение u32 даст 1.5-2× в VDOM и render путях.

  4. Phase 0.3 — flamegraph — подтвердить гипотезы замерами профилировщика (perf record), прежде чем вкладываться в оптимизацию.