by Warren Gaebel
| Mar 12, 2012
This article lists many of the JavaScript performance tips found on the World-Wide Web. The focus is on listing them concisely rather than explaining them. Please read the referenced articles at the bottom for further information. The tips are classified to make it a little easier to find what we need.The author has tested some (not all) of these tips. If testing does not support the tip, it is noted below. Please keep in mind that testing in other environments may yield different results. In all cases, test these tips in production before reaching any conclusions.Website Performance: Taxonomy of Tips introduced a classification scheme to help us organize the many performance tips found on the Internet. JavaScript falls into category #3.1 (the server executes a script).
Reflows
Whenever possible, avoid reflows, which are caused by:
- manipulating the live DOM tree
- changing the layout (e.g., changing the style or className properties)
- resizing the browser window
- manipulating a table
- using static or relative positioning (absolute and fixed are better)
- using measurements (e.g., offsetWidth, offsetHeight, getComputedStyle(), clientHeight, currentStyle())
- changing the font
- adding or removing a stylesheet
- content changes, such as a user typing text into an input box
- activation of CSS pseudo classes such as :hover
- adding or removing a DOM element
Repaints (Redraws)
Whenever possible, avoid repaints, which are caused by:
- adding an outline
- changing a background colour
- changing visibility
Accessing the DOM
- When getting collections of DOM elements, keep the collection as small as possible (1 is best!). Stepping through a larger collection takes more time.
- Whenever possible, avoid manipulating the DOM tree.
- When making multiple changes, work on a tree or element that is not visible to the user and transfer the changes to a visible element afterward.
- Best Example: Use createDocumentFragment() or cloneNode() to create a subtree outside the live DOM tree, work on that subtree, and attach it to the live DOM tree when you’re done.
- Second-Best Example: Make the element invisible (display:none), make the changes, then make it visible again. This is second-best because it triggers two reflows instead of one.
- Make changes as low in the DOM tree as possible.
- Avoid tables. If you must use them, set the table-layout to fixed.
- Avoid JavaScript expressions in the CSS.
- HTMLCollection is not static. It changes as the DOM structure changes. As Nicholas Zakas points out, accessing the DOM while iterating through an HTMLCollection can potentially cause an infinite iteration.
Asynchronous Processing
- Avoid serial execution of code: Use web workers or setInterval() to process code asynchronously. Web workers are not standardized or universally available yet, so setInterval() is the better choice for the time being. Be ready for a bit of a learning curve if you haven’t done this before.
- Use the async or defer attribute to download scripts asynchronously.
Animation
- Reduce the number of frames per second. Example: 100 frames per second will be too much for some browsers.
Garbage Collection
- Delete object properties when you’re done with them.
- Delete objects when you’re done with them.
- After removing a DOM element from the tree, delete it.
Nesting, Looping, & Recursion
- Use for (var i = numberOfIterations; i–;) instead of for (i=0; i<numberOfIterations; i++). Note that this only applies if ican go from large to small instead of small to large.
- Whenever possible, unroll the loop. Example: Use j++;j++;j++;j++;j++; instead of i=5; while(i–) j++;.
- Avoid heavy nesting.
- Anything that can be done before or after the loop should not be done inside the loop. Example: Use x=a.length; before the loop and i<x as the loop condition rather than using i<a.length as the loop condition.
Functions
- Avoid function calls:
- Use primitive operators instead. Example: Use (a < b) ? a : b instead of Math.min(a,b). Example: Use a[a.length] = x instead of a.push(x).
- If the result of the function call will be used multiple times in the following lines, store the result in a variable, then use the variable instead of the function call.
- Inline the function if it’s used only a few times. However, beware the resulting maintenance issue.
- Don’t pass strings to setTimeout() and setInterval(). Pass functions instead.
- Using lazy definitions allows the web page to become interactive sooner, which creates the perception of higher performance. However, some kind of synchronization will probably be needed.
Caching
- If data can be defined in key-value terms and you expect the same calculation to be repeated, use memoization to cache the data instead of recalculating it. See 36:52 in Stoyan Stefanov’s presentation for a quick and easy example of memoization.
Strings
- Use “xxx” instead of new String(“xxx”).
- Calling a method on a literal string requires an implicit conversion to a String object. If you will be doing this multiple times, convert the literal to a String object ahead of time, then use the string object instead. [The author’s tests do not support this tip.]
- Use x += “a”; x += “b”; instead of x += “a” + “b” to avoid creation of a temporary string. [The author’s tests do not support this tip.]
Identifiers
- Use local identifiers as much as possible.
- Use var. Example: Use var i = 0; instead of i = 0;.
- Longer identifiers (the name, not the value) require more processing time.
- If you must work with a global variable, assign it to a local variable and use the local variable instead. [The author’s tests do not support this tip.]
Other
- JSON data is smaller than XML. Smaller is faster.
- Use a function instead of eval. Avoid giving a string to a Function constructor (it uses eval). [The author’s testing shows this tip to be significant.]
- Avoid with.
- Keep try…catch…finally out of performance critical code.
- Use a for loop instead of a for…in loop when possible.
- Whenever possible, avoid new. Example: Use a = [] instead of a = new Array(). Example: Use o = {} instead of o = new Object(). Example: Use “” instead of new String().
- Optimize the order of conditional expressions to take advantage of short-circuit evaluation. Example: Use a && b instead of b && a if a is likely to be false more often than b. Example: Use a || b instead of b || a if a is likely to be true more often than b.
- Avoid anything not included in ECMA-262, 5th Editionstrict mode. Do not yield to browser peculiarities.
- Remove comments and extraneous white space from production code (minification). [The author’s tests do not support this tip.]
References
Building Fast Client-side Searches by Ross. Published 2009.03.18 by Yahoo Flickr at code.flickr.com/blog/2009/03/18/building-fast-client-side-searches. Accessed 2012.02.29. This article discusses how to download a list of over 10,000 contacts in under 200 milliseconds using JavaScript on the front end. It touches on caching, XML, JSON, Ajax, eval, and split.
ECMAScript Language Specification (ECMA-262). Published June 2011 by Ecma International at ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf. Accessed 2012.03.06. This is the official standard for ECMAScript, which is the foundation for JavaScript and other languages. JavaScript’s core syntax is defined by this document.
Efficient JavaScript by Mark “Tarquin” Wilton-Jones. Published 2006.11.02 by Opera at dev.opera.com/articles/view/efficient-javascript/?page=2. Accessed 2012.02.29. This article presents 25 JavaScript performance tips divided into 3 categories (ECMAScript, DOM, and document loading). The tips are relevant to non-Opera browsers also.
Extreme JavaScript Performance by Thomas Fuchs. Published 2009.11.08 by Thomas Fuchs at slideshare.net/madrobby/extreme-javascript-performance. Accessed 2012.02.29. This slideshow presents a handful of JavaScript tips with measurements that prove the tips are valid. Measurements are taken from four commonly-used browsers.
High Performance Kick Ass Web Apps by Stoyan Stefanov. Published 2009.08.06 by JSConf at jsconf.us/2009/stefanov_video.html. Accessed 2012.02.29. Starting at 28:35, this video provides a handful of JavaScript tips, including memoization and multithreading.
JavaScript best practices by Christian Heilmann. Published 2009.03.06 by Opera at dev.opera.com/articles/view/javascript-best-practices. Accessed 2012.02.29. This article is 17 tips to help improve JavaScript performance.
JavaScript Performance Best Practices by Anssi Kostiainen. Published 2011.09.23 by Nokia at developer.nokia.com/Community/Wiki/JavaScript_Performance_Best_Practices. Accessed 2012.02.29. This article is a large number of tips and explanatory text regarding JavaScript performance, including several peripheral issues.
JavaScript Performance Stack by John Resig. Published 2008.02.28 by John Resig at ejohn.org/blog/javascript-performance-stack. Accessed 2012.02.29. This article provides a brief overview of the JavaScript performance stack and shows that JavaScript performance problems may actually be in one of several object models. It notes that speed improvements within JavaScript may affect the object models, too. The graphic helps piece if all together.
JavaScript variable performance by Nicholas C. Zakas. Published 2009.02.10 by NCZ Online at nczonline.net/blog/2009/02/10/javascript-variable-performance. Accessed 2012.02.29. This article examines the “use local instead of global variables” tip in depth and explains why it causes a performance issue. Several browsers are tested and compared.
Reflows & Repaints: CSS Performance making your JavaScript slow? by Nicole Sullivan. Published 2009.03.27 by Nicole Sullivan at stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow. Accessed 2012.02.29. This article describes browser repaints and reflows, the difference between them, and their impact on performance. A few JavaScript/DOM tips are discussed.
A Snapshot of the Yahoo! Photos Beta (from 2006) by Scott Schiller. Published 2009 by Scott Schiller at schillmania.com/content/entries/2009/yahoo-photos-frontend-thoughts. Accessed 2012.02.29. This article describes the author’s work on Yahoo! Photos, with a focus on how they resolved their JavaScript performance issues. Although labelled as “incomplete,” several issues/tips are well-explained.
Speed up your JavaScript, Part 1 by Nicholas C. Zakas. Published 2009.01.13 by NCZOnline at nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1. Accessed 2012.02.29. This article looks at the “execute code asynchronously” tip as it relates to the body of loops. Several code snippets show how to do this in JavaScript.
Speed up your JavaScript, Part 2 by Nicholas C. Zakas. Published 2009.01.20 by NCZOnline at nczonline.net/blog/2009/01/20/speed-up-your-javascript-part-2. Accessed 2012.02.29. This article shows how functions and recursion can benefit from parallel processing. Memoization is also discussed.
Speed up your JavaScript, Part 3 by Nicholas C. Zakas. Published 2009.01.27 by NCZOnline at nczonline.net/blog/2009/01/27/speed-up-your-javascript-part-3. Accessed 2012.02.29. This article continues the discussion of using memoization with recursion.
Speed up your JavaScript, Part 4 by Nicholas C. Zakas. Published 2009.02.03 by NCZOnline at nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4. Accessed 2012.02.29. This article examines various DOM-related performance problems.
Post Tagged with