Speeding up JavaScript: Working with the DOM

In this article on speeding up the web, KeeKim Heng demonstrates a few vanilla javascript techniques which help speeding up the webpages by limiting the number of DOM reflows, which are triggered everytime something changes in our DOM Trees. It emphasises on the interplay of most common web technologies like CSS and javascript and how they should be used in combination rather than separately to fully leverage each ones capabilities in creating a healthy webpage where the number of DOM reflows are minimized.

There are two main topics of discussion in this article:

  1. CSS class switching DOM manipulation: In case we wish to add more than one effect to a particular DOM object, rather than individually adding them via Javascript, we should do it by simply adding another CSS class.

    For example, in place of this:

    function selectAnchor(element) { element.style.fontWeight = 'bold'; element.style.textDecoration = 'none'; element.style.color = '#000'; }

    We could simply do this:

    CSS:

    .selectedAnchor { font-weight: bold; text-decoration: none; color: #000; }

    JS:

    function selectAnchor(element) { element.className = 'selectedAnchor'; }

    This article will help understand when should we resort to tweaking each CSS style individually and when a simple CSS class addition/removal may do the trick.

  2. Out-of-the-flow DOM Manipulation: In case we need to add many elements which are fairly contiguous, then, rather than adding each one individually into their respective place (like insertAfter() in Jquery), we could create everything out of the flow as a DOM Fragment, and then insert it in one go.

The concepts are pretty simple, but the availability of simplifying libraries like Jquery sometimes abstracts away the rather pragmatic issues which stop you from creating turbocharged web-pages.

Author: Lindsey Simon, UX Developer

Recommended knowledge: Basic HTML, basic Javascript, working knowledge of CSS

Reflow is the name of the web browser process for re-calculating the positions and geometries of elements in the document, for the purpose of re-rendering part or all of the document. Because reflow is a user-blocking operation in the browser, it is useful for developers to understand how to improve reflow time and also to understand the effects of various document properties (DOM depth, CSS rule efficiency, different types of style changes) on reflow time. Sometimes reflowing a single element in the document may require reflowing its parent elements and also any elements which follow it.

There are a great variety of user actions and possible DHTML changes that can trigger a reflow. Resizing the browser window, using JavaScript methods involving computed styles, adding or removing elements from the DOM, and changing an element's classes are a few of the things that can trigger reflow. It's also worth noting that some operations may cause more reflow time than you might have imagined - consider the following diagram from Steve Souders' talk "Even Faster Web Sites":

From the table above it's clear that not all changes to the style in JavaScript cause a reflow in all browsers, and that the time it takes to reflow varies. It is also somewhat clear that modern browsers are getting better at reflow times.

At Google, we test the speed of our web pages and applications in a variety of ways - and reflow is a key factor we consider when adding features to our UIs. We strive to deliver lively, interactive and delightful user experiences.

Guidelines

Here are some easy guidelines to help you minimize reflow in your web pages:

  1. Reduce unnecessary DOM depth. Changes at one level in the DOM tree can cause changes at every level of the tree - all the way up to the root, and all the the way down into the children of the modified node. This leads to more time being spent performing reflow.
  2. Minimize CSS rules, and remove unused CSS rules.
  3. If you make complex rendering changes such as animations, do so out of the flow. Use position-absolute or position-fixed to accomplish this.
  4. Avoid unnecessary complex CSS selectors - descendant selectors in particular - which require more CPU power to do selector matching.

In this video, Lindsey explains some simple ways to minimize reflow on your pages:

Additional resources