You can only go as fast as the slowest component

We recently came across a performance wall for one of our application. The application required us to display a massive table and depending on the situation the table would reach over 200 rows and it has about 40 columns. There’s also a lot of client-side activity (the rows are draggable so that user can order them as they like) and massive calculations are done when rows are modified or re-ranked (they each have ~5 input elements). The JavaScript is done with jQuery.

jQuery is a fantastic JavaScript framework that makes development so much easier. If you are not using a JavaScript framework, anything you are doing beside trivial tasks is trying to reinvent the wheel. JavaScript frameworks have solved most of the cross-browser issues you might have and simplifies most common actions. jQuery also has a pretty big list of plug-ins available to improve its capabilities beyond the core library.

Anyway, when the table grows too big (above ~50 rows), the rendering takes a lot of time and the JavaScript starts running slow. The client doesn’t like that so we have to make it snappy.

How to turn a turtle into a rabbit

Improving the rendering speed

So the rendering is slow, I do a quick search on the Internet and consult the Google’s best practices to optimize browser rendering. I already knew that having a lot of CSS classes could be an issue. The Table Drag and Drop jQuery plugin was also a potential problem because it runs something on the table just before the content of the page is rendered to make it “drag and droppable”. So I try rendering the page without any CSS and JavaScript, no luck. Another idea from the best practices was to use fixed columns in the table because supposedly the browser resizes all the columns on each new row to fit the content of the new row (for example, if the new row requires to stretch one or more columns, then the browser will resize all the columns from the row above). So I try to give the columns a fixed width, no luck again.

After trying a few things we decide that instead of trying to make a big table load faster, we will display a smaller table. So I implemented a paging mechanism. So now the user will only see about 20-30 rows (the size is configurable), just what he can handle anyway, more than that is basically noise and information overload.

Improving JavaScript

Then comes JavaScript, more specifically jQuery. It turns out that jQuery is not perfect, more importantly it’s class selector sucks. The class selector lets you select an element (or multiple) by specifying its class like this:

$(".ClassName")

Since our application is done with ASP.NET, we use this selector instead of the ID selector because the ID’s are generated by .NET dynamically which makes them non-predictable (there’s a workaround, but we didn’t think we’d need it). It turns out that the class selector is slow, very slow.

There are a few important rules to follow when using jQuery (if there’s a lot of jQuery). Basically, it comes to this:

ID selector > tag selector > class selector

It makes sense since the ID and tag selectors use native JavaScript methods and the ID selector only selects a single element so it’s faster than the tag selector which selects multiple. The native class selector, getElementsByClassName, is not supported by all browsers yet. A comparison of the frameworks’ implementations vs the native method shows how much faster a native method really is.

Improving the browser

There was another solution other then improving the CSS and JavaScript: changing the browser. The client runs all its applications in IE6 or 7. They are both terrible at rendering big pages and running JavaScript intensive pages.

In other news, IE sucks at everything

When we tried the application in Google Chrome and Firefox, there was absolutely no rendering speed problems or JavaScript performance issues, everything was very responsive.

We showed the client the application in Chrome and they were impressed. Since the client is a huge company with many internal policies, making them switch to another browser is not an easy task and the decision will not be taken lightly. At least they have seen the difference and are considering alternatives for the future (the Chrome Frame plug-in is definitely a contender).

In my opinion, Microsoft should just give up and use WebKit. Everyone except the Internet Explorer team at Microsoft will be happier.

The lesson

In the end, we learned that we needed to improve a few of our practices when it comes to CSS, JavaScript and general rendering, but we also learned that no matter how hard you try, a poor browser can ruin your best efforts.

3 comments
Schmoo on December 1, 2009

jQuery’s class selector can often suck less if you’re more specific, ie, $(‘#someContainer .someClass’);

Michel Billard on December 1, 2009

Yes, the more specific, the better. Specifying the tag before the class also helps.

However, it’s sad to note that this is only an issue for IE as all other browsers perform equally fast with the “slow” class selector.

abowman on December 1, 2009

I’m going through a similar experience witha large table of checkboxes. I started off coding all of the behaviors in jQuery, then had to add LiveQuery to get more flexibility (rows get added and removed). IE6 didn’t like the big table of checkboxes with dozens of events scattered though out. I changed it all to use event delegation and the speed improved across all browsers except, you guessed it, IE6. I chose to use the change event to bind to but IE6 doesn’t bubble the change event. Now several days later I have it working again using click events. What a pain!

Microsoft needs to fix its browser.


Leave a comment
Name (required)
Email (will not be shown) (required)
Website