A jQuery UI Dialog “open” performance issue and how to fix it

jQuery UI is a great way to get good looking, feature packed sites up and running ASAP.  It doesn’t come without it’s costs sometimes though, especially if you use it right out of the box. I recently discovered and interesting issue in jQuery UI surrounding the performance of creating a dialog with a large amount of <table> data in it. Now don’t get me wrong, popping up a dialog with a 1700 row table in it isn’t the panacea of UX design but its definitely not unheard of. In fact I’ve seen this sort of design quite often for mass data display or selection.

So what’s the problem?

Head on over to the demo and click the “Trigger dialog slow” button. Yikes! On my < 2 year old 2.6GHz i5 running the latest version of FireFox it takes about 3.5 seconds to open the dialog containing a modestly widthed table containing 1700 rows. Trying the same in IETester @ IE8 causes the program to crash (real IE8 would probably get it done within 10 – 15 seconds I’m guessing on my box). Meanwhile the user has no idea what is going on and might be wondering with their CPU fan just kicked it up a notch.

Stepping into the jQuery UI source code after using the Firebug JavaScript Profiler it appears that two parts of the jQuery UI Code are causing most of the slow-down:

  • Resizing the dialog box to fit the dimensions specified (~1.5 sec)
  • Finding the first tabbable element and setting focus to it (~1.0 sec)

Well there isn’t much we can do about the first bullet unless we are okay with the dialog not being sized appropriately, but 1 second just to find the first tabbable element? That’s pretty crazy. Unfortunately since both of these bullets exist within jQuery UI code that isn’t extendable we are forced to find another solution. (I may do a pull on jQuery UI’s source to allow a custom tabbable algorithm which can shortcut the expensive “:tabbable” selector in the future)

An easy solution

Head on over to the demo and click the “Trigger dialog fast” button. Wow, much better! That comes up almost instantly on my machine with only a slight delay. What is the huge difference you might ask?

Instead of creating the dialog around the existing large table as seen in “Slow code” below “Fast code” first detaches the children of the future dialog, creates the dialog and then re-inserts the children into the DOM after the dialog is created. This makes all the difference by allowing us to circumvent the painfully slow DOM parsing of all those table rows. The “detach” is also very important because it allows any events, (jQuery or otherwise) to remain wired up to the table elements that will soon make there way back into the DOM.

Slow code

//open a dialog... slowly
$('#triggerDialoglSlow').click(function () {
	var begin = new Date();
	$('#dialogContentSlow').dialog({
		width: 425,
		height: 400,
		draggable: false,
		resizable: false,
		open: function () {
			var end = new Date();
			alert(((end - begin) / 1000) +  " seconds to open a dialog on your beefy box?! Now think of your users on IE7 with a Pentium 4...");
		}
	});
});

Fast code

//open the dialog a bit faster
$('#triggerDialogFast').click(function () {
	var $dialogContainer = $('#dialogContentFast');
	var $detachedChildren = $dialogContainer.children().detach();
	$dialogContainer.dialog({
		width: 425,
		height: 400,
		draggable: false,
		resizable: false,
		open: function () {
			$detachedChildren.appendTo($dialogContainer);
			alert("Now that was a bit faster (sorry, no reliable stopwatch on this one)");
		},
	});
});

12 thoughts on “A jQuery UI Dialog “open” performance issue and how to fix it

  1. You are the man. I was skeptical honestly but this has made a serious improvement on the load time of my dialog. Nice work, this will be stashed away for a rainy day! 🙂

  2. Wonderful! Had a form with hundreds of checkboxes in multiple tabs and this reduced dialog opening time from 17s to ~1.3s.
    Thanks alot!

  3. Wow. Thank you! Note, detaching on the close function also helps speed the closing of a beefy dialog. This really helped me. Took a 6-8second open down to less than 1.5. Stellar information. Appreciate you posting it.

  4. Thanks, sir! This was a HUGE help. Such a simple trick; they should have built it into the library!

    I improved my load speed by a factor 10!!!

    John

Leave a Reply

Your email address will not be published. Required fields are marked *

Proudly powered by WordPress | Theme: Cute Blog by Crimson Themes.