Поле renderer: SVG против Canvas

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


SVG-рендерер

SVG (Scalable Vector Graphics) представляет собой DOM-ориентированную модель визуализации, где каждый графический элемент — это отдельный узел в дереве документа.

Архитектура отрисовки

SVG-рендерер создаёт графику через стандартные элементы:

  • <rect>
  • <circle>
  • <path>
  • <text>

Каждый элемент остаётся частью DOM, что делает его доступным для CSS-стилей и событий браузера.

Ключевые особенности

SVG-рендерер обладает следующими характеристиками:

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

  • Удобная интеграция с DOM Элементы можно стилизовать через CSS и отслеживать через стандартные события браузера.

  • Относительно высокая стоимость при большом количестве элементов При тысячах и десятках тысяч узлов производительность резко падает из-за нагрузки на DOM.

  • Хорошая поддержка accessibility Элементы остаются семантически частью документа.

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

Основные проблемы проявляются при увеличении сложности сцены:

  • большое количество DOM-узлов приводит к деградации FPS
  • сложные анимации вызывают перерасчёт layout
  • взаимодействие с миллионами точек становится неэффективным

Canvas-рендерер

Canvas использует растровую модель отрисовки через <canvas> элемент, где вся сцена рисуется в одном bitmap-слое.

Архитектура отрисовки

Canvas работает через API 2D-контекста:

  • сцена не разбивается на DOM-элементы
  • каждый кадр перерисовывается целиком или частично
  • графика хранится в пикселях, а не в структуре документа

Ключевые особенности

Canvas-рендерер оптимизирован для больших объёмов данных:

  • Высокая производительность при больших датасетах Тысячи и миллионы точек обрабатываются значительно быстрее, чем в SVG.

  • Меньшая нагрузка на DOM Отсутствуют тысячи узлов, вся сцена — один элемент.

  • Гибкость при сложной визуализации Подходит для динамических сцен, плотных scatter plot, heatmap и потоковых данных.

  • Более сложное взаимодействие с элементами Нет прямого доступа к объектам сцены; требуется hit-testing.

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

  • потеря масштабируемой чёткости (зависимость от разрешения)
  • сложность стилизации отдельных элементов
  • более трудная интеграция с DOM-событиями
  • необходимость ручной обработки интерактивности

Сравнение SVG и Canvas

Производительность

SVG:

  • эффективно до сотен/тысяч элементов
  • деградация при росте DOM

Canvas:

  • стабильно работает с десятками и сотнями тысяч точек
  • производительность зависит от CPU и перерисовки

Качество отображения

SVG:

  • идеальная векторная чёткость
  • независимость от DPI

Canvas:

  • зависит от разрешения canvas
  • возможна пикселизация при масштабировании

Интерактивность

SVG:

  • нативные события на элементах
  • простая реализация hover, click, selection

Canvas:

  • требуется вычисление попадания (hit detection)
  • интерактивность реализуется через дополнительную логику

Память и структура

SVG:

  • высокая нагрузка на DOM и память браузера
  • каждый элемент хранится отдельно

Canvas:

  • минимальная нагрузка на DOM
  • вся сцена хранится как пиксельный буфер

Конфигурация renderer в Vega и Vega-Lite

В Vega-Lite выбор рендерера задаётся через объект конфигурации:

const spec = {
  data: { url: "data.csv" },
  mark: "circle",
  encoding: {
    x: { field: "x", type: "quantitative" },
    y: { field: "y", type: "quantitative" }
  },
  config: {
    renderer: "canvas"
  }
};

В Vega (низкоуровневый слой) параметр задаётся при инициализации View:

const view = new vega.View(vega.parse(spec))
  .renderer("svg")
  .initialize("#vis")
  .run();

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

Vega компилирует декларативное описание в внутреннее представление сцен (scenegraph). Дальнейшее поведение зависит от выбранного backend:

При SVG

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

При Canvas

  • scenegraph используется как источник для rasterization
  • каждый frame перерисовывается в canvas context
  • обновления требуют полной или частичной перерисовки слоя

Влияние renderer на интерактивные элементы

Интерактивность в Vega (tooltip, selection, brush, zoom) ведёт себя по-разному:

SVG:

  • hit detection основан на DOM events
  • точность высокая
  • проще реализуются сложные hover-состояния

Canvas:

  • используется spatial indexing (quadtree / bounding boxes)
  • события эмулируются поверх пиксельного слоя
  • требуется дополнительная оптимизация при больших наборах данных

Производительные сценарии использования

SVG демонстрирует лучшие результаты в случаях:

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

Canvas становится предпочтительным при:

  • scatter plot с десятками тысяч точек
  • потоковые данные (real-time charts)
  • heatmap и плотные визуальные матрицы
  • визуализации с частой перерисовкой

Гибридные подходы и оптимизация

В сложных приложениях часто применяется комбинированная стратегия:

  • Canvas используется для основного слоя данных
  • SVG применяется для оверлеев (оси, подписи, интерактивные элементы)

Также встречается динамический переключатель renderer:

  • SVG для статического режима
  • Canvas при включении высокой плотности данных

Особенности масштабирования и DPI

SVG автоматически адаптируется к DPI без дополнительных настроек.

Canvas требует учёта devicePixelRatio:

  • увеличение разрешения canvas для Retina-дисплеев
  • ручное масштабирование контекста

Без этого визуализация теряет чёткость при увеличении масштаба экрана.


Роль renderer в архитектуре Vega

Renderer является конечным слоем pipeline:

  1. Vega-Lite spec
  2. Vega specification
  3. Dataflow transformation
  4. Scenegraph
  5. Renderer (SVG / Canvas)

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