Why Not SVG?

SVG is literally called Scalable Vector Graphics. It's a vector format. It lives in browsers. It scales infinitely.

Why wouldn't we use it for a vector editor?

The Appeal

Declarative. Describe what you want, not how to draw it:

<rect x="10" y="10" width="100" height="50" fill="red"/>

DOM integration. SVG elements are DOM nodes. Event handlers, CSS styling, accessibility—all work.

Inspect with DevTools. See every shape in the Elements panel. Debug visually.

Built-in animation. SMIL animations, CSS transitions, all free.

Native browser rendering. The browser handles rasterization. You handle shapes.

For icons, illustrations, and simple graphics, SVG is excellent.

The DOM Problem

Each SVG element is a DOM node. DOM nodes are expensive.

<svg>
  <rect id="rect1" .../>
  <rect id="rect2" .../>
  <!-- 5000 more rectangles -->
</svg>

5000 rectangles = 5000 DOM nodes = browser struggling.

Measure it:

Objects SVG Render Canvas Render
100 2ms 0.5ms
1000 25ms 3ms
5000 150ms 12ms
10000 400ms+ 25ms

At 10,000 objects, SVG drops below 3fps. Canvas stays smooth.

Update Overhead

Change a shape? Update the DOM.

element.setAttribute('x', newX);
element.setAttribute('y', newY);
element.setAttribute('width', newWidth);
// Triggers reflow, repaint

Every attribute change can trigger layout recalculation. Batch updates help, but DOM mutation is inherently slow.

Canvas: modify data, call draw(). No intermediate DOM layer.

Styling Limitations

SVG has fills and strokes. But:

No per-segment dashing:

<!-- This path has one dash pattern for all segments -->
<path d="M0,0 L100,100 L200,0" stroke-dasharray="5,5"/>

Limited blend modes: SVG filter and feBlend exist, but:

No stroke alignment: SVG strokes are always centered. Inside/outside stroke? Build it yourself with duplicate paths.

Text Nightmare

SVG text is deceptively complex:

<text x="100" y="100">Hello</text>

Looks simple. Then:

Canvas2D has measureText(). Skia has full text shaping. SVG requires building a text engine.

Transform Inheritance

SVG transforms cascade through the DOM:

<g transform="translate(100, 100)">
  <g transform="rotate(45)">
    <rect x="0" y="0" width="50" height="50"/>
  </g>
</g>

Convenient for simple cases. Problem:

Reading back world coordinates requires walking the DOM tree, accumulating transforms. The browser does this automatically for rendering, but you can't easily access intermediate results.

Modifying child positions while respecting parent transforms is matrix math you have to do yourself anyway.

Z-Order Rigidity

SVG renders in document order. Back-to-front.

<svg>
  <rect id="background"/>
  <rect id="foreground"/>  <!-- Always on top -->
</svg>

Reorder z-index? Move DOM nodes.

foreground.parentNode.insertBefore(foreground, background);

DOM reordering triggers reflow. In Canvas, z-order is just array indices.

Filter Performance

SVG filters are powerful:

<filter id="blur">
<feGaussianBlur stdDeviation="5"/>
</filter>
<rect filter="url(#blur)"/>

But:

Same operations in WebGL: one draw call with shader.

When SVG Makes Sense

Static illustrations. Icons, logos, diagrams. Load, display, done.

Simple interactivity. Hover effects, click handlers on shapes. Few elements.

CSS-driven animation. Transitions and keyframe animations on a handful of elements.

Accessibility requirements. SVG elements can have ARIA attributes. Screen readers understand the structure.

SEO needs. Text in SVG is indexable. Canvas content isn't.

The Hybrid Approach

Some editors use SVG for UI, Canvas for content:

<div class="editor">
  <canvas id="content"/>  <!-- Thousands of shapes -->
  <svg id="ui">           <!-- Selection box, handles -->
    <rect class="selection"/>
    <circle class="handle"/>
  </svg>
</div>

SVG overlays handle UI elements (few objects, needs events). Canvas handles content (many objects, needs performance).

We considered this. Complexity wasn't worth it. All Canvas/Skia is simpler.

Summary

SVG's DOM model is both its strength and weakness:

Strength: Integration with web platform, CSS, events, accessibility.

Weakness: Performance ceiling at scale, update overhead, limited styling control.

For a vector editor with thousands of objects, complex effects, and 60fps interaction:

SVG won't get you there.

It's not the rendering engine. It's the architecture. DOM nodes are the wrong abstraction for graphics-intensive applications.

Next: Why Not Raw WebGL? →