Canvas-рендерер в Lottie Web представляет собой альтернативный способ
отрисовки анимаций, при котором графическая сцена композируется не через
DOM/SVG-элементы, а через 2D-контекст <canvas>. Это
принципиально меняет модель производительности, структуру обновлений и
характер потребления ресурсов.
Основная задача canvas-рендерера — максимально быстро преобразовывать векторную анимацию, экспортированную из After Effects через Bodymovin, в растровые кадры с минимальными затратами на управление DOM и перерисовку отдельных узлов сцены.
Внутренняя модель Lottie строится вокруг композиции (composition),
слоёв (layers) и элементов (shapes). Canvas-рендерер переводит эту
иерархию в последовательность команд
CanvasRenderingContext2D.
Ключевые этапы кадра:
В отличие от SVG-рендерера, где каждый элемент существует как DOM-нода, canvas-версия работает в режиме immediate mode: каждый кадр полностью перерисовывается.
Каждый тик анимации инициирует пересборку сцены:
clearRect)beginPath / moveTo
/ bezierCurveTosave /
restoreОсобенность модели заключается в том, что никакие элементы не сохраняются между кадрами. Это уменьшает накладные расходы на DOM, но увеличивает нагрузку на CPU при сложных сценах.
Canvas-рендерер демонстрирует предсказуемую производительность при большом количестве объектов благодаря отсутствию DOM-дерева.
Основная нагрузка canvas-рендерера связана с обработкой векторных контуров. Каждый shape преобразуется в последовательность команд Canvas API.
Типичный pipeline:
fill) или обводка
(stroke)При сложных анимациях количество path-команд становится критическим фактором производительности.
Оптимизация часто сводится к сокращению числа сегментов кривых Безье и уменьшению количества отдельных shape-слоёв.
Canvas-рендерер реализует маскирование через операции контекста:
globalCompositeOperationКаждая маска фактически превращается в дополнительный проход рендеринга. При наличии вложенных масок возникает каскад отрисовок, что увеличивает стоимость кадра нелинейно.
Особенно затратны:
Каждый слой в Lottie имеет собственную матрицу трансформации:
Canvas-рендерер применяет их через:
context.setTransformsave/restore с последовательными
transformМатрицы пересчитываются каждый кадр, даже если трансформация не изменилась, если отсутствует механизм кэширования состояния слоя.
Оптимизация в этом контексте заключается в:
Lottie Canvas-рендерер может использовать кэширование отдельных элементов сцены:
Кэширование особенно эффективно для:
При этом стоимость кэша выражается в:
Canvas-рендеринг зависит от плотности пикселей экрана. При высоких
значениях devicePixelRatio происходит масштабирование
буфера:
scale(dpr, dpr)Без учёта DPR возникают артефакты:
С ростом DPR линейно увеличивается стоимость fill/stroke операций.
Canvas и SVG-рендереры решают одну задачу разными подходами.
SVG:
Canvas:
При росте числа элементов canvas демонстрирует более стабильное время кадра, тогда как SVG начинает страдать от DOM-операций и пересчёта стилей.
Canvas-рендерер эффективен в сценариях, где приоритетом является стабильный FPS:
Менее эффективен в случаях:
Производительность Canvas-рендерера напрямую зависит от частоты вызова render loop.
Основные механизмы управления:
requestAnimationFrameПри перегрузке CPU возможна деградация до:
Canvas API накладывает значительные ограничения на производительность визуальных эффектов.
Наиболее затратные операции:
shadowBlurshadowOffsetfilter цепочкиКаждая из этих операций может приводить к созданию промежуточных буферов, что резко увеличивает стоимость кадра.
Внутри реализации используются типичные оптимизации графических движков:
save/restoreОсобое значение имеет система dirty flags: только изменённые части сцены пересчитываются, остальные повторно используют предыдущие вычисления.
Рендер canvas строго привязан к главному потоку JavaScript. Это создаёт ограничение:
В некоторых архитектурах используется: