Saturday, April 2, 2011

When does DOM access slow down rendering?

Page speed is becoming a pretty hot topic. There are quite a few tools out there helping developers to make their UIs more responsive. My personal favorite is Page Speed which was recently released for Chrome and as an online tool and existed for a while for Firefox. This kind of tools can give you precious information about your website's performance, but if your JS execution still takes a long time, then repaints and reflows could be main cause of your problem.

How does a browser render a page?

  1. Browser reads the HTML and constructs a DOM tree (tag=node, text=text node and root=html element)
  2. Browser parses css...keep in mind the order rules are being picked up is (order is provided from stronger to weaker rule):
    • IDs with !important declaration in a rule
    • Classes with !important declaration in a rule
    • Elements with !important declaration in a rule
    • Inline styles
    • IDs
    • Classes
    • Elements
  3. Browser constructs the render tree, which is the DOM tree but with all styling rules applied. Every node in the render tree is called a frame or a box (from the W3C box model).
  4. Last but not least...browser starts drawing (paint) the tree nodes on the screen.

Be aware! Repaints and reflows may be really expensive!

When we change data were used to construct the render tree then we force the browser to do one of the following:
  • parts or complete render tree is revalidated and nodes dimensions are recalculated...this is called reflow. There's always one reflow, for the initial construction of the render tree.
  • parts of the screen are updated (because of changes dimensions of a node or because of stylistic change). This is called repaint, or redraw.

As most of us may already know, a script's running time is usually spent on executing the JS byte code, although what we may not realize is that oftentimes a lot of this time is also spent in performing DOM operations triggered by the script. Reflow is one example of these. The larger and more complex the DOM, the more expensive this operation may be. Reflows and repaints may cause your UI to appear sluggish.

What calls cause repaints and reflows?

  • Add, remove, update DOM nodes
  • Hide a DOM node with display: none (reflow and repaint)
  • Hide a DOM node with visibility: hidden (repaint only)
  • Move, animate a DOM
  • Add a stylesheet
  • User action like resizing window, changing font size, or scrolling

Can we be more specific?

Sure we here is a list of properties and methods that can cause reflow in webkit as they are given by Tony Gentilcore:

clientHeight, clientLeft, clientTop, clientWidth, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth

Frame, image
height, width

getBoundingClientRect(), getClientRects()

computeCTM(), getBBox()

getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()


getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()

So how can we fix that?

Don't worry there is still hope! Browsers are becoming smarter and smarter and they are trying to save us some time. So in this case they are smart enough to realize that these operations cost a lot and help by setting up a queue of changes our scripts require and perform them in batches. The queue keeps growing for an amount of time and then at some point its flushed causing only one reflow. But we have to be careful...
  • offsetTop, offsetLeft, offsetWidth, offsetHeight, scrollTop/Left/Width/Height, clientTop/Left/Width/Height, getComputedStyle() are forcing the browser to reflow in order to return the correct values. So, be cautious and call these elements only when you really need them.
  • Batch methods that manipulate the DOM separately from those that query its state. If this is not possible perform your DOM changes "offline", i.e use a documentFragment to hold your changes temporarily.
  • Change class names and not styles, if this is not possible, again change cssText property and not style

In conclusion, we have to be aware of how browsers work and try to reduce the amount of work they have to perform, otherwise we end up with not responsive and slow UIs, that make users unhappy. When you build UIs, keep always in mind the render tree and how many changes browser will have to make to it once your JS is executed.



  1. Is there any alternate way to get the offsetHeight of an element without triggering reflow ?

  2. Simply Desire To Say Your Article Is As Astonishing. The Clearness On Your Put Up Is Simply Excellent And I Can Think You're Knowledgeable On This Subject. Fine Along With Your Permission Let Me To Take Hold Of Your RSS Feed To Stay Up To Date With Drawing Close Post. Thanks 1,000,000 And Please Keep Up The Rewarding Work. Judi Indonesia Online Teraman

  3. This comment has been removed by the author.

  4. This comment has been removed by the author.

  5. Greetings! I Know This Is Kinda Off Topic But I'd Figured I'd Ask. Would You Be Interested In Exchanging Links Or Maybe Guest Writing A Blog Article Or Vice-versa? My Site Goes Over A Lot Of The Same Subjects As Yours And I Think We Could Greatly Benefit From Each Other. If You Might Be Interested Feel Free To Shoot Me An E-mail. I Look Forward To Hearing From You! Great Blog By The Way! beritamoto

  6. Hi, Great.. Tutorial is just awesome..It is really helpful for a newbie like me.. I am a regular follower of your blog. Really very informative post you shared here. Kindly keep blogging. If anyone wants to become a Front end developer learn from Javascript Training in Chennai . or learn thru JavaScript Online Training in India. Nowadays JavaScript has tons of job opportunities on various vertical industry. JavaScript Training in Chennai