5 ms·
It sounds like most of their problems were with using the browser SVG event handlers (or perhaps the framework). They could have written their own event system
by robocat 3y ago
It sounds like most of their problems were with using the browser SVG event handlers (or perhaps the framework).
They could have written their own event system for SVG (e.g. using event handlers on document), which would have fixed the gripes they blamed on SVG events. They wrote their own event system for canvas, so probably not much more difficulty in coding work?
Performance is the remaining issue that isn’t clear that SVG would meet. I assume SVG painting could be as fast as canvas painting. I am assuming if you attach no events to SVG elements, you remove the event performance issues (well, replace them with performance issues in your own custom event handlers, but no worse than canvas). Surely removing all the now unneeded SVG-grab-handle-elements (“DragBox”) that were only there to capture events would also improve performance (painting and event capture). Canvas is using imperative drawing primitives, and SVG can use composable primitives - both can be rendered by GPU. Canvas updates (eg. during dragging) require heavier imperative updates, while SVG primitives can theoretically be offloaded to the GPU. I can’t guess performance differences and performance delta probably strongly depends on browser, driver, and GPU.
Assuming you write your own event handling stack:
> the mouse only hits SVG elements inside their painted region
Fixed (as good as canvas)
> we could use things like pointer-events to disable certain interactions at certain times
Unnecessary (plus lowers stress on rendering?)
> Having every element produce a whole load of DOM elements for React to manage becomes a problem for performance when every element attaches event handlers, has to manage their lifecycles, observe state, etc., etc.
Fixed with document events
> Interactivity limitations. With our SVG renderer, each element managed its own interactions, which made it impossible to drag elements that were underneath other elements. This is a surprisingly common when making complex maps.
Fixed with document events
> Maintainability. However, with every element attaching its own interactions, there is a tendency for every interaction to know about every other, checking if it should be enabled or not.
Fixed with document events
> Another maintainability issue is the proliferation of event.stopPropagation() calls in the code. These are to stop events bubbling up through the complex DOM structure and allowing other components to handle events.
Fixed with document events (equivalent difficulty to canvas).
When writing complex code you learn that stopPropagation() is evil. Writing code to avoid it requires skills. IMHO stopPropagation should never be in any complex codebase (or perhaps with rules to prevent errors).
> We also have a few places where we have awkward setTimeout() calls
Oh my god, no! Terrible hack with terrible consequences, as they discovered. setTimeout() introduces very evil race-conditions, and testability issues. An alternative which isn’t much better is to use async to get microtasks, so at least you are not reordering events/tasks. IMHO in any modern codebase setTimeout should be banned or extremely restricted when it is absolutely needed.
SUMMARY
Basically, it sounds like the team needs some more experienced GUI developers.
I would bet good money they are trading one set of problems for another, and ending up with a codebase that is less maintainable.
I can only hope the article is not written by the lead developer - heaven help them if it were.
Opinions are my 10c as a custom framework developer (admittedly only one product that was not as complex as a GUI editor - that is why the inexpert mistakes sound so painful to me - although I could also avoid and detect problems because it was my own framework: depending on a third party framework makes it a heap harder to fix systematic faults).
- hicksyfern 3y agoAuthor here. I know this is the orange site and we have to expect this type of comment, but still… I’ve been building software for more than 20 years, and using React since it came out. You’re right that this event handling system isn’t exclusive to canvas. But then I’m not sure if you read the first part of the article where we talk about the other big reason: performance. Your assertions that setTimeouts should be banned show immaturity. There are some cases where certain browsers do things in a different order and you really are required to use a hack like that. You also neglect the fact (and this also points to your immaturity) that products are built by a number of people over a long period of time, with different constraints on them as things change. The SVG approach was done for good reasons and the code made sense for what it was for initially. Then things got more complex and people started making more complex maps. What we also found is that the complexity of maps people made increases with our performance gains: the faster the app is, the more people do with it. I haven’t got time to go into everything either in the articles or certainly this reply, but I’d ask you to have a look at yourself and decide if you really want to be That Guy on HN.
- robocat 3y agoYeah, I should not have been so inflammatory and I should have limited my comments to where I have deep experience. The comments on preventDefault() and setTimeout() in particular repeat my own hard-won experiences: it is unfortunate you had to experience the same pain. In the previous article, maybe the first third is you fighting your framework, which is admittedly what happens to us all if we are on the bleeding edge with performance issues. Certainly you are not the first team to find that canvas is a better solution. In the first article you say “whenever the element’s coordinates or the viewport changed, we would re-render the element”, and you go on to talk about SVG versus canvas. HOWEVER it is impossible to tell whether your underlying performance problems actually stem from SVG (or SVG+events, or SVG+React). I can believe that canvas is more performant and more predictable, but your first article lacks enough detail to actually blame SVG. DOM changes, React, JavaScript could and probably did have severe impact on overall performance. That was the point I tried to make (admittedly, very poorly, since it isn’t clear you could avoid DOM changes in particular). My main gripe with your second article was that you were concentrating on problems to do with SVG events and React - a problem that you resolved with your own event stack on canvas. That solution could have worked for SVG, although as you wrote in your first article, would not resolve your performance problems when painting. > Your assertions that setTimeouts should be banned show immaturity. There are some cases where certain browsers do things in a different order and you really are required to use a hack like that. I guess I had that coming, but I stand by the statement. I learnt about setTimeout(0) caused-problems when working with DHTML controls (pre-frameworks) and frameworks that had nasty heisenbugs: intermittent hard-to-reproduce bugs that would surface because of events racing timeouts. One reason for writing a custom framework was that it was more reliable for users than depending on code that was out of our control: just the same as you are writing about. The framework KendoUI had been chosen by another at one point, and it was particularly troublesome for me. I believe using setTimeout() to avoid browser bugs is diabolical (or framework bugs even worse), because all too often you end up with further troubles that can be extremely hard to reproduce or diagnose. I worked hard to avoid setTimeout(), replumbing code at times, but it virtually always could be avoided with enough work (especially with complete control over event handlers). I stand by “setTimeout should be banned or extremely restricted when it is absolutely needed” because setTimeout(0) is a plaster that too many developers use to paste over cracks. Yes, browsers sometimes force us to accept the ugliest of hack solutions, to achieve some usability goal or avoid some browser bug. All the best. Without a doubt you are far more experienced than I in this area, and certainly you have had a ton of experience wrestling with canvas versus SVG, and I certainly appreciate your article about how you won using canvas. Fighting performance problems in browsers requires a certain intransigence and flexibility, and I feel your pain and your glory from my own past experiences doing the same. (Edited to add extra depth and details). I think that I was so skeptical because the articles lack many technical details that compare SVG performance versus canvas. It compares a React+SVG codebase, with a rewritten canvas codebase. I can believe that SVG is worse than canvas, but neither article has much that is convincing on that point except that the rewrite was successful (which is admittedly a good prior that canvas is better). it is possible you are too quick to dismiss the experience of others. Background: I was nearly 100% focused on front end work, mostly heavy DOM/JavaScript from 2006 for a bit over a decade; but I have worked in a variety of software dev roles for a few decades (embedded, DB, client-server, Windows apps, front-end, POS, plus other random bits). I can definitely say I am well above average at writing reliable, performant, usable code (maybe due to my embedded programming background?).