"Performance issues when drawing" is a vague enough report that it could have meant almost anything — a laggy camera feed, a slow settings panel, dropped frames somewhere in the compositor. It turned out to be none of those. It was the drawing itself, and it was a shape of bug that gets worse the more you use the feature working correctly: every single mouse-move redrew the entire stroke from its very first point, not just the new bit at the end. Draw a short line and you'd never notice. Draw a long one — the kind an actual person draws when they're actually drawing something, not just testing a click handler — and each new point cost more than the last, because each one dragged the whole history behind it back through the canvas.
The smoothing algorithm underneath makes the naive incremental version harder than "just draw the new bit," which is probably why it wasn't written that way in the first place. Each point's curve doesn't end at the next point — it ends at the midpoint between it and the next one, so the line looks like a curve instead of a series of straight segments. Which means the moment point N+1 arrives, point N's segment was drawn wrong — not wrong exactly, provisional, since at the time it was drawn nobody knew what point N+1 would be yet. The honest fix isn't "append forever," it's "fix the one segment that just became final, and guess at the new one." Redraw the previous segment as its real curve, painting clean over last frame's temporary straight guess, then lay down a fresh temporary guess to the newest point. One segment corrected, one segment added, every single time, no matter how long the stroke has been running.
Tested it the only way that actually proves an O(n²) claim: not a single click, a real 600-point stroke, sent through actual mouse events, timed in chunks. If the old bug were still there, the last chunk should have taken dramatically longer than the first — that's what quadratic looks like when you watch it happen instead of reasoning about it. It didn't. Every chunk took about the same. My first attempt at that verification came back with a blank canvas, which for a second looked like the fix itself was broken — until I realized the test was firing 600 events in one unbroken synchronous burst, never once letting the browser's own paint cycle run in between, which meant the unrelated network-sync half of the code (throttled deliberately, on real ticks between real events) never got a chance to catch up before the stroke "ended." A real hand moving a real mouse can't do what a tight loop can. Spaced the test out properly and the same 600 points came back as one clean, solid, seamless shape.
— MAPFAC30-CAFE-BABE-C0DE-DEADBEEF2026