
How Bad is DOM Interaction Really? - andyshora
http://andyshora.com/how-bad-is-dom-interaction-javascript.html
======
ender7
The real hits to performance do not come from "I did X writes" or "I did Y
reads", but rather from situations such as "I did X writes interleaved with Y
reads, which caused Z reflows". Or "I needed to update a tiny part of the
screen but triggered a full-page repaint". Or "I'm doing complex animation X,
but am not triggering hardware acceleration."

Reflows are very expensive. So are repaints. Chrome dev tools will allow you
to detect issues with both of those.

~~~
tyleregeto
There are a couple of excellent videos on developers.google.com that dig into
this a little bit. I highly recommend watching the following video where two
Google developers analyze some real world sites and fix the performance
issues:
[http://www.youtube.com/watch?v=z0_jD8nO5Zw](http://www.youtube.com/watch?v=z0_jD8nO5Zw)
There are some great tips in it.

------
kellegous
I mean no offense to the author, but speaking of the DOM as if it is uniform
in terms of performance seems silly. Pretty much every piece of API in the DOM
has its own semantics and performance expectations (even if it's presented as
a JavaScript property). Reading Element.offsetLeft, for instance, is a whole
different world from reading Node.nodeType.

Just looking at their implementations in WebKit should tell you why:

[https://github.com/WebKit/webkit/blob/master/Source/WebCore/...](https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/Element.cpp#L638)

[https://github.com/WebKit/webkit/blob/master/Source/WebCore/...](https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/Element.cpp#L327)

~~~
esailija
Also, the code doesn't call into DOM directly but uses jQuery .html() for
"reading" and .html(Math.random()) for "writing".

The case is extremely misrepresented indeed.

~~~
AsymetricCom
The DOM is a failed institution trying to grab on the the ledge before it
falls into the abyss. W3C should be disbanded and HTML5 abandoned. JavaScript
and it's ilk should be boycotted by users as well. This kind of complexity
should exist on the server, not in the browser. I understand that people want
to run complex apps in the browser. It's a bad idea in general but where it's
needed, it should be PLATFORM DEPENDENT, implementing the tools that keep that
platform safe. ie iOS, Windows, whatever. We are still in the browser wars,
why are we so keen to adopt standards that aren't standard?

DOM Lvl 4 even features GC! Can we not see why this is a bad idea?!? Keyboard
bindings also do not belong in a "standard". I wish this would get more
attention by serious developers, but I think that most people who know better
wouldn't care and aren't interested in understanding and digging into a lame
standard. It's a land grab, only enterprises can and will ever be able to
implement it correctly and completely, as the standard spreads to consume more
of the user's space.

Here are some people who agree with me:

[http://www.adamcrume.com/blog/archive/2009/12/23/the-java-
do...](http://www.adamcrume.com/blog/archive/2009/12/23/the-java-dom-api-
sucks)

[http://programmers.stackexchange.com/questions/147451/whats-...](http://programmers.stackexchange.com/questions/147451/whats-
so-bad-about-the-dom)

~~~
thezilch
WTF is this? I don't even know where to begin with this crackpot of a post.
You suggested nothing of value and just spout a bunch of FUD.

To your friends that agree with you from 2009, use `querySelectorAll` for a
non-live NodeList, assuming he has kept up with JS actually having evolved and
converging on standards.

I bet you flip your lid, too, to learn your server-side-only dystopia is
running on top of JS (Node) services.

~~~
gruseom
Can you please not be so abrasive on HN? Your points may be correct, but your
tone is exactly what we're trying hard to avoid here.

~~~
GalacticDomin8r
Ah the white knight. Please please I beg you be nice.

------
malandrew
No discussion of repaint and reflow? You can't leave a discussion of those out
when talking about the cost of DOM manipulation.

You absolutely can touch the DOM, but should do so through and interface that
manages or eliminates repaint and reflow.

~~~
ghostdiver
I have same feeling,

Making single frame of JS code to run fast is cool and dandy, but eventually
browser will have to make freeze and do reflow+repaint. Eventually it will
make profiling harder, think about caching .offsetHeight etc. properties. It
does decrease script execution time, but it does not make your app to work
faster.

~~~
jcampbell1
The important trick to know is, don't mix DOM modification with DOM
measurement. Measuring the DOM is what triggers the DOM modification queue to
get flushed.

if you do something like

    
    
       $('a').each(function(k,e){
          $(e).append('<span>' ...);
          var width = $(e).width()
          // do something with the width;
       }
    

If you have code like the above, it is going to cause a repaint on each
iteration. If you unroll it into three separate loops, one that does dom
modification, one that does dom measurement, and another that does
modification, then you will drop the number of repaints from potentially 100s
to just 2.

~~~
ghostdiver
It does not trigger repaint on each iteration.

------
ihsw
Most DOM performance issues arise from jQuery (mis)usage, and fortunately
there is documentation for that:

[http://learn.jquery.com/performance/](http://learn.jquery.com/performance/)

It's brief and quite informative.

------
pcunite
After 10+ years as a performance leaning C++ desktop app developer I'm looking
for any and all tips to make JavaScript (jQuery too) work in _perceivably_
faster ways. I'm use to threading database calls, using message queues, and
views updating themselves from caches. It’s a new world for me and feels
somewhat like a step backwards.

Here I come html5!

~~~
oscilloscope
You can use queues when creating a large number of elements. Use
requestAnimationFrame and each frame pop some elements off the queue to render
them. This will help prevent the page from locking up during render events.

~~~
PavlovsCat
Also, when adding many elements (or not so many, but over and over), add them
to a DocumentFragment [ [http://developer.mozilla.org/en-
US/docs/Web/API/DocumentFrag...](http://developer.mozilla.org/en-
US/docs/Web/API/DocumentFragment) ] first, and then attach that to the DOM in
one piece (one big DOM update is better than many small ones).

------
bkjelden
Caching jQuery selectors may result in a speedup, but as with all caching
systems I've run into nasty, hard to trace bugs that were the result of stale
cached jQuery selectors.

So I'd add the caveat to caching jQuery selectors that standard premature
optimization rules still apply.

~~~
bdg
Caching them in local fucntion scope should be harmless. For instance:
grabbing #x, using it inside a decision structure and iterator. Caching #x as
a global constant is probably setting you up for some fun debuging later.

------
Semiapies
These timings are all remarkably random, even with 10k repetitions.

~~~
esailija
In both selector tests, the code calls `.html()` as well. It also uses a
direct #id selector, I.E. does not "search the entire DOM" like it says.

------
eagsalazar2
TL;DR: Writing is slower, debounce resize event handlers, cache references to
dom nodes or jquery selections.

Really the resize thing is sort of bs also because it is such an incredibly
rare thing to handle (99% of all apps will never ever require handling resize
except to _test_ responsive designs)

------
chime
Did not know Underscore comes with a debounce function. I always implemented
my own.

~~~
saraid216
There is also a _.throttle

