Engineering Journal
Schema Editor
Schema Editor

Rendering Handles Inside Your SVG Is Not a Performance Problem. It Is an Architecture Problem.

2026-06-04

TLDR

The argument against canvas overlays for selection handles is usually about complexity: a second rendering layer, manual hit testing, coordinate mapping. The argument for SVG handles is simplicity. The SVG handles are simpler until zoom changes, then they require compensation code that grows without bound. The canvas overlay is the right architecture and about the same complexity once you include the compensations.


What the Industry Does

Most SVG diagram editors that predate the canvas overlay pattern render handles inside the SVG. mxGraph (draw.io) has a long history of SVG handles with zoom-dependent sizing. Many open-source editors on GitHub render handles as <rect class="handle"> elements inside the diagram SVG.

The pattern persists because it works well enough for simple cases and is straightforward to implement. SVG handles are just elements. You add them, remove them, position them in the SVG coordinate system. It feels natural.

Why It Fails for This Problem Class

SVG handles inherit the diagram's coordinate rules. Everything in SVG scales with zoom. There is no way to have a fixed-pixel-size element inside an SVG that uses viewBox for pan/zoom. You can compensate by dividing the handle size by the zoom factor, but this requires tracking zoom state in handle rendering and updating all handles on every zoom event.

SVG elements are clipped by the viewBox. A handle at the edge of the viewport disappears when the element is panned to the boundary. You can compensate by extending the viewBox, but this lets elements be placed outside the visible area.

SVG hit testing via getBoundingClientRect on children does not always account correctly for the viewBox transform across browsers. You can compensate by computing positions manually. But at that point you are doing the coordinate math that the canvas overlay does explicitly.

The compensations are not free. Each adds code that must be maintained, is correct for one configuration, and breaks when another configuration changes.

The Better Approach

SVG owns the diagram content. Canvas owns the ephemeral UI layer: handles, snap guides, cursor indicators, selection rectangles, alignment lines. The split is clean because the two layers have different requirements:

The canvas overlay satisfies all UI chrome requirements by default. Handles are drawn at fixed pixel sizes. The canvas is never clipped. Hit testing reads from an explicit list. The coordinate mapping is one function using getScreenCTM().

What You Give Up

The canvas overlay requires manual hit testing. Native browser event handling (clicking an SVG element fires click on that element) does not apply to canvas-drawn shapes. You implement hit testing by storing hit zones and checking them on pointer events.

For most diagram editors, this is straightforward: the hit zone list is small (selected elements only), checking it is O(n) where n is the handle count, and the check happens on every pointer event. This is fast.

The more significant cost is maintenance: the overlay render function must be called whenever the diagram state changes (selection changes, pan/zoom, resize). In practice this means scheduling a render after every operation. Using requestAnimationFrame to debounce ensures at most one render per frame.

When the Common Pattern Is Right

Use SVG handles when: the diagram is static (no pan/zoom), the handle size can scale with zoom, the diagram is not large enough for the overlap issues to matter, and you will never need to test hit zones independently of the SVG event system. For simple, bounded-zoom diagram editors, SVG handles are correct and simpler. For any editor with unbounded zoom and viewport panning, the canvas overlay is the right architecture.

Read this post in the full Engineering Journal →