# Optimizing a jquery user interface application

I'm working on a javascript intensive user-interface application. (At least it's intensive for me, it's my first serious javascript project).

I have a few jquery functions going whenever a div is rolled over or mouseout. For example there are some divs which are draggable objects, and so when they are mouseovered, the cursor must look ready to move. But my interface so slow that my boss thinks my code isn't working, when in fact it is, but it's just slow and so the user has to sometimes wait upto 2-3 seconds for the cursor to look as expected, or for a div to look as expected. Just an example. My code is something like below, I can't reproduce it entirely or properly since my company has copyrights on this, so I've written some lines as comments just to give a clear idea of the way I'm doing things. There's more to it, but this is basically what it's like:

$.fn.extend({ mouseoverBox: function() { return this.each(function() { var$this = $(this); if(!$this.hasClass('ready'))
{   if($this.hasClass('activated')) {$this.removeClass('activated');
}
$this.addClass('ready'); } var img_id =$this.children('.theimg').attr('id');
//someitem.children('somechildren').remove();
//$this.draggable(); //$this.resizable();
if($this.hasClass('unlocked')) {$this.draggable( "option", "disabled", false );
$this.resizable( "option", "disabled", false ); }$this.bindUnlock();
});
}
// end mouseoverBox
});


Now this is just the mouseoverBox function, which is triggered like myBox.mouseoverBox(). on the mouse over event. Then of course this plugin is calling bindUnlock() which has simple operations like changing classes and adding classes to a menu. Also, before any mouseover, there's usually been a mouseout out of another div... so as you can see there's a lot of stuff happening. There aren't usually more than 10 interactive divs on at any one moment though. How can I optimize this kind of code? I haven't given every specific but trust me most of the relevant is pretty much just like this.

I've already gzipped my javascript, css, images and fonts. I also tried minifying using the Yahoo Compressor but it actually bloated one of my files instead of compressing it.

-
Can't help with the timing, but a small refactoring suggestion: replace the body of the first if with: $this.removeClass('activated').addClass('ready'). Depending on what you need, it may be suitable to replace both if's with$this.removeClass('ready').removeClass('activated').addClass('ready') –  Sean Feb 9 '13 at 13:44

Without actual code, we cannot review it if it actually contains significant issues. Thus, I've set forth guidelines instead.

# Compression

The real help that compression does is actually speeding up loading times. Unless you are actually loading scripts on demand on mouseover, then you might need to compress them.

However, a better solution is to actually preload these resources, or load them in parallel, and execute once available. That's pretty much how RequireJS does things. That way, you are not actually waiting for resources. The same thing is also true for other resources like fonts, images, cursors, videos and all the rest.

# Other scripts

Anyways, there are a lot of things that could cause your script to go wrong, and that includes other scripts on the page. Due to the fact that JS is naturally single-threaded (unless made to thread), any blocking operation, be it in other scripts or within your script, could potentially be slowing down your entire operation. An example is a very long loop, or SJAX (Synchronouse XHR).

To make sure that it's not your script that's breaking apart, try isolating your development enviroment to only your script and a minimal version of the UI and without other scripts. Also, test other functionalities on the page without your script to verify that it's another script that is causing the problem.

# >700ms === lag

Yes, that's true. According to a YUI video on their YouTube channel, 200ms is considered "instant" in the perspective of the user. That also explains that game latencies of <200 are best. However, in your case, 2-3 seconds? The user has already left your page by then.

Aim for responsiveness that are less than or are in the range of 200-300ms. And yes, your boss is for real and knows what he's doing.

# Hey! Cache!

Your script is potentially DOM heavy by its looks and description. But DOM manipulation is heavy work. Cache as much as possible whenever possible, especially on elements that don't change over the lifetime of the page.

Also, minimize fetching stuff on the DOM.

-
Thanks! Yes I'm sure the problem would the DOM manipulation - I'm constantly doing that in my code. It's basically a WYSIWYG editor that allows users to play around with text boxes and upload images and move them around too, so I have no choice. But could you please elaborate a bit on the "caching"? –  user961627 Feb 9 '13 at 12:55
@user961627 caching. If certain elements don't change throughout the life of the page, it makes no sense calling \$('selector_here') every time to get that element. Instead, you store it in a variable and refer to that variable instead. –  Joseph the Dreamer Feb 9 '13 at 12:57