Tuesday, December 21, 2010

New design

I've made a major upgrade on the blog today. Since I first started this blog, the template tools at blogger.com has become way more advanced and at the same time, way more easy. So enjoy and let me know if the new design is a total miss.

Tuesday, December 14, 2010

10 tricks that will make your jQuery enabled site go faster

During the last few weeks, I've had the chance to go more in depth with jQyery and general site performance. I've found some techniques that makes my site go much faster. I don't know if they're all best practice, but this article is meant to at least give you some good ideas.


$(document).ready(e) vs $(window).load(e)


The .ready(e) function fires when a dom element is ready. That's why we use it on the document element. When the document element is ready, the page is also, sort of. Actually the page is not ready until the window is fully loaded with images and other resources, but we're allowed to start manipulating the DOM at an earlier stage. I recomend doing your DOM manipulation, resizing, setup menus etc first and then start your ajax calls once the page is fully rendered.

So put your design oriented code in the $(document).ready(e) function and your data oriented code in the $(window).load(e). That way, the page components come to place at an earlier stage and that creates the illusion of speed.


Load JSON from string

In order to avoid the extra cost of doing a page request you can actually include JSON in the page as a string. For instance, I use a jQuery framework to build my menu, but the page lags a bit while waiting for the external scripts that loads the menu elements. I found that the user experience is much faster if I include the menu items as a javascript string at the bottom of the page. The main page will take some milliseconds extra loading, but the menu lagging will dissapear. I then set up the menu in the $(document).ready(e) function and set up the menu before the page data loads.


var menuJSON = '[{....}]'
$(document).ready(function () {
var menuObject = $.parseJSON(menuJSON);
}


Store repositories in memory

If you load JSON or XML from another script with ajax, keep the returned object in a variable in the window scope. That way, you can do live search and sort operations quickly without loading external resources again. I know some like to do sort in the database, but modern browsers can do it quite quick. It depends on the size of the dataset of course.


var userRepository;
$(window).load(function(){
userRepository = $.ajax(....);
doSomething(userRepository);
});


Setup events last

You can save a bit of loading time by adding events last. First layout, then data, and then events. Events aren't visible and we want the visible parts of your web site to load first, right? What you could do is to disable buttons until they're loaded with events. This example uses jQueryUI.



$(document).ready(function(){
$(":button").button("disable");
});


and then, once an event has been added do all your button code:


(window).load(function(){
$("#button").click(....);
$("#button").button("enable");
(...)
});


Unbind events

If you never unbind your events, you could potentially consume quite a lot of unnecessary memory. Even worse you could stack up double events and your click function or keypress trapper could be executed twice. In order to make sure that there's only one click funtion on a DOM element do the following:


$("#button").unbind("click");
$("#button").click(....);


.empty() vs html("")

This one is related to the one above. If you write .html("") when you want to empty a div or a list, then there's no guarantee that the events assigned to the child DOM elements are unbound. The jQuery manual states:

"To avoid memory leaks, jQuery removes other constructs such as data and event handlers from the child elements before removing the elements themselves."

So, always use .empty() in stead of .html("")


Load your javascripts at bottom of the page

The new best practice is to load CSS in the head and javascripts at the end of the body. It actually works. If you do, then the page will have read the rest of the page before starting to manipulate it. Hence it appears much faster.

Since javascripts are getting quite heavy in size, it is actually better to let the page load divs and images before large chunks of javascripts. jQuery is just under 80 kb, jQueryUI another 200 kb and I bet you have a few other scripts as well. It all adds up and makes your site slower.

Also, rumors has it that some web search engines only reads a certain amout of text before leaving for another page, and therefore you will be able to present more of the important stuff first.


Don't use a content delivery system

Unless you run a site with tens of thousands of visitors daily or your bandwith costs are very hight, I see no reason to use a CDN. I think what they are trying to achieve is a caching effect. If your visitors allready have the recent jQuery framework cached from Google, they won't have to when they go to your site. But in my experience, CDNs are always a performance drag. They all tend to go slower than my on web hosting and that looses the whole meaning of using these services.


Download the custom version of jQueryUI

The full version of jQueryUi is just under 200kb in size. If you only use button functionallity, you only touch the tip of the iceberg. The custom version of jQueryUI which only holds the core funtionallity and the button package only takes about 13,9 kb. Do the maths, the custom version takes the jQueryUI from being the heaviest file you load on your page to being on of the smallest.

This also explains a problem with using a CDN, since they only have the large version on their site (probably).


RTFM

I mean it, are you familiar with the special selectors in jQuery? How about the .live(...) funtion? It's all in the jQuery documentation. Use it.



kick it on DotNetKicks.com

Thursday, December 09, 2010

The ad blocker mystery

I've just come to realize how important it is for me to run an ad blocker at work. First of all I don't like opening a web site and then start looking for the real content amongst the blinking ad banners. I just don't. And it seems to me that norwegian web sites are the worst. Try visiting www.dinside.no without safety goggles and you'll se what I mean. That site is plain awfull sometimes. www.digi.no has som much ads that they don't even have room for a main article image.

Anyways
We've had some problems with ad blockers blocking items on our web site, so today I've spent some time figuring out how they work. Turns out, there's nothing magical about them. They simply block content based on script naming. Consider these two scripts:

createNew.asp?id=1671

vs

createNew.asp?id=1671&adName=myName


I load them both into an iframe after the page first has been rendered, but one of them is stopped. The last one actually gets blocked because of the querystring variable adName.

Solution
Choose your names wisely. Our system actually is for making ads, so names containing ad*** seemed quite natural at one time. The guys over at Sitepoint has some articles on this topic and this one is worth a read:

http://blogs.sitepoint.com/2009/05/27/file-naming-important/