I watched the javascript performance talk from Nicholas C. Zakas at Google Tech Talks: Nicholas C. Zakas: Speed Up Your JavaScript.
- Scope Management
- Loop optimization
- About HTMLCollection Live objects
- Document Fragments - postponing reflow
Scope Management
The tip given to improve efficiency is to use local variables, because variables which are in the local scope are accessed first. Every time a global or a variable from a prototype or a dot object variable is accessed twice. Use a local variable.
Another issue related to the scope aspect is that using functions and closures comes with a certain cost.
Loops Optimization
Loops can be optimized in different ways, when avoiding unnecessary work.
About HTMLCollection Live objects
The presentation explains that the collection returned by methods such as: .getElementsByTagName, ... return HTMLCollection objects which remain 'live', that is they get updated. A typical example is the following loop:
var divs = document.getElementsByTagName('div');The collection in divs is an HTMLCollection. The body of the loops goes over the loops and adds a div for every object in the collection. But since new objects are added to the loop every time one goes through the loops, the loops never ends !!!!!
for (var i = 0; i< divs.length; i++){
var div = document.createElement('div');
document.body.append(div);
}
DocumentFragment - postponing reflow
Reflow occurs when the the size of the elements on the page are recalculated. To improve performance it is useful to minimize the number of reflows.
In general, Nicholas C. Zakas explained that reflow happens at five particular moments in browsers:
- Page load
- browser window resize
- adding and removing elements
- setting style attribute of elements
- (sometimes) accessing the style elements of the nodes
To prevent useless reflows, one can use a document fragment in order to create a quite complete element as a document fragment and then add it to the DOM. In this way, reflow is only performed when the element is added to the page.
To minimize the access to the style attributes of elements, a better way to perform that is to change the class of the element, i.e: use .className instead of .style.