Many times have we been posting the recommendation to speed up your DOM Element lookups by using unique IDs or at least a tag name. So, instead of using $(“.wishlist”) you should use $(“div.wishlist”) which will speed up lookups in older browsers. If you want to lookup a single element then give it a unique ID and change your call to $(“#mywishlist”). This will speed up lookup in older browsers from 100-200ms to about 5-10ms (times vary depending on number of DOM elements on your page). More on this in our blogs 101 on jQuery Selector Performance or 101 on Prototype CSS Selectors.

Case Sensitive ID handling results in interesting performance impact

With the recommendation from above I was surprised to see the following $(“#addtowishlist”) call with a huge execution time difference in IE7, IE8 and FF 6:

Same $("#addtowishlist") call with huge performance differences across browsers revealing not only a performance problem
Same $(“#addtowishlist”) call with huge performance differences across browsers revealing not only a performance problem

So – why is this call taking that long?

Turns out that the ID attribute of the element in question (“addtowishlist”) is actually defined as “addToWishList”. As Class and Id are case-sensitive (read this article on the Mozialla Developer Network) the call $(“#addtowishlist”) should in fact return no element. This leads us to an actual functional problem on this page. The element exists but is not identified because the developer used a different name in the $ method as defined in HTML. The performance difference is explained by a uniqueness of Internet Explorer 6 and the way jQuery implements its $ method.

jQuery 1.4.2 is the version used on the page we analyzed. The following screenshot shows what happens in Internet Explorer 7:

jQuery iterates through all DOM Elements in case the element returned by getElementsById doesn't match the query string
jQuery iterates through all DOM Elements in case the element returned by getElementsById doesn’t match the query string

The screenshot shows the dynaTrace Browser PurePath for IE 7. getElementById in fact returns the DIV tag even though it shouldn’t based on HTML standard specification. jQuery adds an additional check on the returned element. Because the DOM elements ID “addToWishList” is not case-equals with “addtowishlist” it calls its internal find method as fallback. The find method iterates through ALL DOM Elements (1944 in that case) and does a string comparison on the ID element. In the end, jQuery doesn’t return any element because non matches the lower case ID. This additional check through 1944 elements takes more than 50ms in Internet Explorer 7.

Why the time difference in IE 7 and FF 6?

IE 8 and FF 6 execute so much faster because getElementById doesn’t return an object and jQuery therefore also doesn’t perform the additional check.

Lessons Learned: We have a functional and performance problem

There are two conclusions to this analysis:

  • We have a functional problem because IDs in HTML in JavaScript/CSS are used with mixed case and therefore certain event handlers are not registered correctly.
  • We have a performance problem because IE7 incorrectly returns an element leading to a very expensive jQuery check.

So – watch out and check how your write your ID’s and ClassName’s. Use tools to verify your lookups return the expected objects and make sure you always use a lookup mechanism that performs well across browsers.