Когда Canvas быстрее SVG

В экосистеме Vega и Vega-Lite выбор между Canvas и SVG напрямую влияет на производительность, масштабируемость и характер взаимодействия с визуализацией.

SVG представляет графику как структуру DOM-элементов, где каждый графический примитив — отдельный узел. Canvas, напротив, использует растровую модель: сцена отрисовывается в одном bitmap-контексте через последовательность команд рисования.

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


Архитектурная модель SVG и её ограничения

SVG (Scalable Vector Graphics) в браузере интегрирован в DOM. Каждый элемент графики (circle, rect, path, text) становится полноценным узлом дерева документа.

Ключевые особенности SVG-рендеринга:

  • Каждый графический объект существует как DOM-node
  • Стили применяются через CSS и inline-атрибуты
  • События (hover, click) обрабатываются на уровне отдельных элементов
  • Перерисовка инициируется через layout + style recalculation

Производственные издержки SVG:

При росте количества элементов начинает доминировать стоимость:

  • построения и поддержания DOM-дерева
  • recalculation styles
  • layout / paint pipeline браузера
  • управление тысячами event targets

При 10–50 элементах разница между SVG и Canvas минимальна. При 1 000+ элементов стоимость DOM начинает расти нелинейно.


Canvas: модель растрового конвейера

Canvas использует императивный API отрисовки, например:

const ctx = canvas.getContext("2d");
ctx.fillStyle = "steelblue";
ctx.fillRect(10, 10, 100, 50);

Каждая команда напрямую записывает пиксели в буфер кадра без создания промежуточных DOM-объектов.

Особенности Canvas:

  • отсутствует DOM-дерево графических объектов
  • нет индивидуальных узлов сцены
  • отрисовка выполняется в одном контексте
  • обновление часто означает полную перерисовку слоя

Когда Canvas начинает выигрывать у SVG

Переход к Canvas становится оправданным в случаях, когда стоимость DOM-природы SVG превышает стоимость полной перерисовки bitmap.

1. Большое количество визуальных элементов

SVG начинает деградировать при тысячах и десятках тысяч элементов:

  • scatter plots с 10k–100k точек
  • тепловые карты
  • dense line charts с множеством сегментов

Canvas в этих сценариях выполняет фиксированное количество операций рисования без увеличения DOM-overhead.


2. Частые обновления данных

При анимации или потоковых данных:

  • SVG вынужден пересчитывать стили и layout
  • Canvas перерисовывает кадр целиком

При высокой частоте обновления (30–60 FPS) стоимость DOM становится узким местом.


3. Интерактивные визуализации с динамическим слоем

В Vega рендеринг часто делится на слои:

  • фоновые сетки
  • основные геометрические примитивы
  • интерактивные оверлеи

Canvas эффективно обрабатывает базовый слой, минимизируя количество объектов, участвующих в hit-testing.


Vega: переключение между Canvas и SVG

В Vega рендерер выбирается на уровне runtime:

vegaEmbed("#view", spec, {
  renderer: "canvas"
});

или

renderer: "svg"

Поведение внутри Vega:

  • спецификация остаётся неизменной
  • меняется только backend рендеринга
  • одинаковая декларативная модель графа
  • различается стратегия исполнения команд

Vega-Lite и компиляция в Vega

Vega-Lite транслирует высокоуровневые описания в Vega-spec.

Canvas-выигрыш проявляется именно на этапе исполнения скомпилированного графа:

  • Vega-Lite задаёт трансформации (aggregation, binning, filter)
  • Vega выполняет вычисления и рендер
  • Canvas минимизирует стоимость визуального слоя

DOM overhead в SVG как узкое место

SVG страдает от фундаментальной особенности браузерного движка: DOM — это универсальная структура, оптимизированная не только под графику.

Источники затрат:

  • layout recalculation при изменении атрибутов
  • style resolution через CSS cascade
  • memory overhead на каждый узел
  • GC pressure при массовом обновлении

Даже простая операция изменения координаты тысячи точек требует тысяч DOM updates.


Canvas и стоимость перерисовки

Canvas устраняет DOM-overhead, но переносит нагрузку в другую область:

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

Фактически оптимизация смещается от структуры DOM к управлению кадром.


Сравнение моделей исполнения

SVG pipeline:

  1. изменение данных
  2. обновление DOM-элементов
  3. style recalculation
  4. layout (при необходимости)
  5. paint отдельных узлов

Canvas pipeline:

  1. изменение данных
  2. очистка контекста
  3. последовательная отрисовка
  4. финальный bitmap commit

Масштабирование по числу элементов

Поведение производительности можно обобщить:

  • SVG: O(n) с высоким коэффициентом на каждый узел DOM
  • Canvas: O(n) без DOM, с более дешёвой операцией на элемент

При малых n SVG выигрывает за счёт инкрементальности. При больших n Canvas становится стабильнее.


Hit-testing и интерактивность

SVG обладает встроенной системой событий:

  • pointer events на уровне элементов
  • автоматическое определение попадания курсора

Canvas требует дополнительного слоя:

  • ручной hit-testing
  • пространственные индексы (quadtree, spatial hash)
  • пересчёт координат в логические объекты

Vega компенсирует это внутренними структурами сцены, но стоимость остаётся.


Сложные сцены и композиция слоёв

Canvas особенно эффективен при композиции:

  • многослойные графики
  • фоновые grid + overlay marks
  • анимации переходов

Причина — отсутствие необходимости обновлять независимые DOM-поддеревья.


Ограничения Canvas

Несмотря на производительность, существуют фундаментальные ограничения:

  • ухудшение качества масштабирования при zoom
  • отсутствие нативного CSS styling на уровне элементов
  • сложность редактирования отдельных объектов
  • рост стоимости полной перерисовки при сложных сценах

SVG сохраняет преимущество в сценариях:

  • малое количество элементов
  • высокая необходимость интерактивности на уровне узлов
  • документно-ориентированная визуализация

Поведение Vega при выборе рендерера

Внутренне Vega может оптимизировать сцену:

  • агрегация элементов в батчи
  • кэширование path-объектов
  • минимизация state changes Canvas context
  • группировка однотипных marks

Это позволяет Canvas использовать более эффективный draw-call pipeline.


Типовые сценарии, где Canvas стабильно быстрее SVG

  • scatter plots с десятками тысяч точек
  • streaming dashboards с обновлением >10 FPS
  • визуализация логов и событий
  • heatmap с высокой плотностью данных
  • динамические графики сигналов

В этих случаях стоимость DOM и style recalculation в SVG становится доминирующим фактором.


Итоговая модель выбора рендеринга

Поведение системы определяется балансом:

  • количество графических элементов
  • частота обновлений
  • сложность интерактивности
  • требования к масштабируемости DOM

Canvas выигрывает там, где критична скорость отрисовки большого числа примитивов и минимизация DOM-операций, тогда как SVG сохраняет преимущество в структурной выразительности и точечном управлении элементами сцены.