Speed up your JavaScript: The talk
Steve Souders recently invited me to participate in his Web Exponents speaker series at Google. Periodically, people come in to give hour-long tech talks about various topics. Since I had most recently worked with Steve on his new book, Even Faster Web Sites. I wrote a chapter on JavaScript performance, and Steve asked if I would come and share some tips along those lines to the folks at Google. In following along my series of blog posts about JavaScript performance, I entitled this talk, Speed up your JavaScript.
The talk today went very well (aside from some humorous technical glitches). Attendance was good and there were a lot of good, insightful questions both during the presentation and afterwards. My slides are available now and there will be a video coming out possibly next week. Topics include how to optimize:
- Scope management
- Data access
- Loops
- DOM
After the talk, I went to lunch with Steve and Doug Crockford (who attended the talk as well) for a little more discussion about the state of web technology. Overall, a very fun experience.
One of the biggest points I want to make about this talk, both for those who were there and those who were not, is that I’m not saying to do things all the time. The techniques presented in the talk are intended as a guide for those who have noticed performance bottlenecks and need to know how to fix them. Optimization without measurement is fruitless, and I’d be doing everyone a great disservice by presenting these techniques as “must follow” under any and all circumstances. Always measure the performance of your code using a profiler (shameless plug: YUI Profiler is pretty sweet) and then determine what you should do to speed things up.
Doug pointed out to me afterwards that he thought a lot of the early topics in the talk generally don’t provide a big performance gain. I think his statement has some validity, as everything is related to the code base in which you’re developing. When I worked on My Yahoo!, we had a lot of trouble with loop performance and did a lot of optimizations for it. Others might not have bottlenecks around their loops. All of the information in my talk is based on performance issues I’ve faced in my career, and though some may be obscure, I believe it’s important to talk about those issues so they can be a guide for others who find bottlenecks in these areas. The worst thing we can do is avoid coming up with solutions for rare problems, because rare problems need solving too.
After the talk, we ran into Mark Miller, the research scientist at Google behind Caja. He hadn’t seen the talk but word of its topics apparently traveled quickly to him. He mentioned that it seemed like my talk was geared at programming in poorly-performing browsers. That’s entirely true, my talk is geared towards those poor souls (along with myself) who are stuck developing for Internet Explorer, Firefox, Safari, and Opera. Those with the luxury of only developing for Chrome or any other browser using a JIT JavaScript compiler don’t need to worry about performance issues (so far). Mark seemed to be concerned about my recommendation to avoid using the native forEach() method (as defined in ECMA-262, 5th Edition). In my talk, I stated that this implementation is much slower than using a regular JavaScript loop, which is true (it’s very much slower). This is true in Firefox and Chrome, both of which have implemented the method natively. Mark asserted that ECMAScript 5 won’t be implemented in anything but the most performant JavaScript engines, which would use inlining to improve performance. Though good to hear, it made me realize that I should have explained more completely the purpose of this talk: to help developers who are dealing with crappy browser performance right now.
The experiments I ran for the talk (and mentioned in the video) are here:
You may not use everything in this talk, and that’s fine. I do hope you’ll keep this information in the back of your mind and return to it should you notice performance issues in your JavaScript. I’ve been in situations where milliseconds were being counted under close scrutiny, and I hope that this information will help developers who are in a similiar situation.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




13 Comments
Very interesting slideshow. Hope the video presentation will be out soon.
razvantim on June 5th, 2009 at 10:40 am
the video is already available here: http://www.youtube.com/watch?v=mHtdZgou0qU
excellent presentation btw!!! I’m glad I found this site!
I understand that, for eg, yahoo mail cares about this, because there must be a huge js behind this, but I think that in almost all sites the improvement in permormance won’t be noticed, as you said in this post. But this is still extreme valuable, especially for those who update and build js frameworks.
It is very sad have to develop for IE. I think all developers should make a plot against IE. just kidding xD
Leandro on June 7th, 2009 at 12:22 am
I just watched that youtube video. That was an awesome presentation. I learned a lot from it.
I have a question though, let’s say i have a calendar which is a table tag, row tag, etc.. and it contains text values in it. I have a button that changes the text node values of the calendar. Does it cause a re-flow every time i change the value of a text node?
CJ on June 8th, 2009 at 1:41 am
Thanks for the kind words, CJ. Changing the value of a text node in a table will, I believe, cause reflow unless you’ve set the table to be
table-layout: fixed.Nicholas C. Zakas on June 8th, 2009 at 11:05 pm
It’s always worth pursuing performance gains that work – even if they seem insignificant in the single user case, all that processing time for millions of page views has to outweigh the cost of a few minute’s extra thought and typing.
Nick Tulett on June 25th, 2009 at 6:51 am
I’ve just watched the YouTube presentation. Great presentation, clear explanation and DocumentFragment is my new hero
.
razvantim on June 27th, 2009 at 2:02 pm
Just been reading through your PDF from Velocity and on p. 37 you give an example of caching document in a local variable. Do you happen to know if this optimisation is exploited within jQuery or YUI?
For instance is it much better to use:
var doc = document;
var button1 = doc.getElementById(“btn1″);
var div9 = doc.getElementById(“div9″);
than
var button1 = $(“#btn1″);
var div9 = $(“#div9″);
or am I just clutching at premature optimisation straws now?
Nick Tulett on July 3rd, 2009 at 4:42 am
Well, to answer my own question,
function pureJS(){
var doc = document;
for (var i=0;i<10000;i++) {
var button1 = doc.getElementById(“btn1″);
var div9 = doc.getElementById(“div9″);
};
}
is 20x faster than
function jQ(){
for(var i=0;i<10000;i++){
var button1 = $(“#btn1″);
var div9 = $(“#div9″);
}
}
For the jQuery version, init() is called 80,000 times!
In the single case, the difference is one sixth of a millisecond, so I can see that it might not always pay off…
Nick Tulett on July 3rd, 2009 at 5:46 am
@Nick – Yes, oftentimes the change in doing something a single time is so small as to not be worthwhile. The biggest changes are always realized when there are multiple operations being performed repeatedly. Also factor in that the jQuery $() function isn’t simply passing through to document.getElementById(), there is some processing on the input string and other magic that happens under the covers, which is why $() will always end up being slower than document.getElementById() when compared across multiple operations.
Nicholas C. Zakas on July 4th, 2009 at 1:39 pm
What about string?
It’s mentioned in many optimization recommendations to use array join() function instead of multiple string concatenation.
I found in my own tests instead that the concatenation methodi is faster then array.join(). Here’s my code:
var times = 5000000;
function run_test1()
{
var res = ”;
for(var i=0; i < times; i++)
{
res += ‘abcd’;
}
}
function run_test2()
{
var res;
var arr = [];
for(var i=0; i < times; i++)
{
arr[arr.length] = ‘abcd’;
}
res = arr.join();
}
Paolo Chiodi on September 18th, 2009 at 9:52 am
@Paolo – join() is always faster in Internet Explorer. Other browsers have implemented improvements to string concatenation that make join() slower.
Nicholas C. Zakas on September 18th, 2009 at 10:30 pm
@Paolo I ran some similar tests myself and was surprised to find that concatenation was actually faster than join() for small strings. My test basically compared this:
var result = ‘test’ + ‘test’;
To this:
var arr = ['test', 'test'];
var result = arr.join();
For this very simple case scenario, the times for concatenation were definitely faster for all browsers tests I ran, as long as the strings were small enough. For IE6, the array method took 3 times longer than regular concatenation.
It’s only when I increased the string length (100 characters instead of 4) and the number of strings (10 instead of 2) where performance improvements with join() were noticed. However, even with this test, regular concatenation was still slightly faster (not 3x faster this time, but more like 1.3x faster). I’m planning on writing a little article with my results after I’ve finished testing everything.
David Calhoun on January 22nd, 2010 at 1:26 am
[...] JavaScript – Part 3Speed up your JavaScript – Part 4Further Info:Google Tech Talks YouTube ChannelSpeed up your JavaScript (article by the speaker discussing the video)HTML 5 and Internet Explorer 9Speaker: Giorgio SardoGiorgio Sardo talks about HTML5, CSS3, SVG, and [...]
Seven Must-See Videos and Presentations for Web App Developers - Smashing Magazine on July 18th, 2010 at 3:58 am
Comments are automatically closed after 14 days.