top | item 27679432

(no title)

kgr | 4 years ago

When we designed to UI library for FOAM in 2011 at Google, we did extensive benchmarking, and discovered that DOM calls were very slow and that we could greatly improve performance by batching them. Yes, in the end, you still need to make DOM calls to update the DOM, but you were better off forming all of your DOM's html on the JS side and then just make one call to element.innerHTML = myHTML and then hookup listeners if necessary. The JS to C++ bridge was very slow, and so you were better off to make one large call and then have C++ parse your HTML and build all of the DOM itself than you were to make many small DOM calls adding each element and attribute value individually. However, I was recently writing a document on the performance advantages of FOAM's virtual DOM, but rather than just assert the fact without proof, I wrote some benchmarks to demonstrate... that it is in fact no longer faster. As a result, we're replacing FOAM's UI library, called U2, with a new non-virtual DOM library called U3.

discuss

order

lhorie|4 years ago

innerHTML has been slower than the DOM API for a few years. React had a big refactor at one point to rip out innerHTML logic precisely due to this. To make matters more interesting, the order of DOM API calls also mattered. In IE, building a DOM tree bottom up was significantly slower than building it top down (meaning, no large document fragments for you!). There are also a ton of other quirks: `.textContent = ''` being faster than removeChild, appendChild vs insertBefore vs replaceChild, childNodes random access, properties being faster than attributes (which is a rabbit hole of its own because SVG), cloneNode being faster but nigh unusable in a framework setting, orders of magnitude difference in performance due to data structure polymorphism...

Squeezing performance out of DOM manipulation is really tricky because the performance profile of pretty much everything changes frequently without rhyme or reason.

nobleach|4 years ago

Not to travel too far off the main topic, but I use this exact fact to demonstrate to new developers why I prefer a developer that looks things up instead of relying on what "everyone knows". When Jeremy Keith's DOM Scripting book was written many years ago, it claimed that DOM methods were much slower than innerHtml. And that was true. If we all just took that as gospel, we'd be WAY off base.

So I'll take the dev that looks things up, as there's much more possibility they're operating on more up to date information.

Consequently, this is why I also tell people to stop repeating "this is a best practice" a year or so after something is discovered. It's a "common practice". You don't have enough info to know if it's truly "best".

madhadron|4 years ago

In my personal experiments, I ended up using document fragments. I wasn't doing FRP, just classic MVC, but a view (which was a JavaScript object) had a reference to the DOM elements it was responsible for. If it needed to replace them, it created a document fragment, did anything that needed to be done in there (including having children redraw) and then swapped out that fragment. This gave very nice performance.