Making jQuery better | NetEngine

Making jQuery better

Stan Thursday, 4 April 2013

At the beginning of writing this post I had an idea to write about integration of javascript unit tests for a project. The challenge is to refactor all those beautiful functions and event listeners into something proper for running unit tests on.

Generally speaking I should split event listeners and key functions into separate files and modules, to be able to easily include them in test specs. But before I touch that, it will be for my next post, I would really want to write about a couple of jQuery optimisation techniques which seem obvious but we so often forget using them when we are in a rush to do something fabulous.

So, at this point let’s assume you are a front end developer or server side guy intending to hook up a bunch of UI elements on a page to make restful API doing what it always does. And likely you’re going to start from binding event listeners to a page’s elements. There is a good way to organise it without messing up many levels of nested function scopes, which reduce performance by making long chains of call stacks .

    // this is bad
    $(document).ready(function() {
        $('#allOkay').click(function(e) {
            $('#woweffect').slideUp(function() {
                // ...
            });
        });
        $('#allAwesome').load(url + ' #unicorns', function() {
            // ...
        });
    });

    // this is better
    var AppEventListenrs = {
        onReady: function() {
            $('#allOkay').click(AppEventListenrs.slideUpElement);
            $('#allAwesome').load(url + ' #unicorns', AppEventListenrs.onUnicornsLoad);
        },
        slideUpElement: function(e) {
            $('#woweffect').slideUp(AppEventListenrs.onSlideUp);
        },
        onSlideUp: function() {
            //...
        },
        onUnicornsLoad: function() {
            //...
        }
    };

    $(document).ready(AppEventListenrs.onReady);

All right!

Once we’ve done with event listeners we may want to build dynamic html and append it to a page. And at this point we keep in mind that touching DOM always comes at cost. If you’re adding a heaps of elements into the DOM do it all in one shot rather than one element at time.

    // this is bad
    $.each(allBirdsOfAustralia, function(i, bird) {
        var newBird = '<li>' + bird + '</li>';
        $('#flock').append(newBird);
    });

    // this is better
    var fragment = document.createDocumentFragment();
    $.each(allBirdsOfAustralia, function(i, bird) {
        var newBird = '<li>' + bird + '</li>';
        fragment.appendChild(newBird);
    });
    $('#flock')[0].appendChild(fragment);

And the last thing everybody generally always forgets is that it’s a good idea to check if an object exists before we call any of its methods. As for example, jQuery executes a number of useless methods to determine that an object doesn’t exist. So with this in mind don’t forget to check the length of your selection before adding some magic to it.

    // this is bad
    // jQuery performs a couple of functions, before realise it's empty
    $('#emptySelection').slideUp();

    // this could be better
    var $mySelection = $('#nosuchthing');
    if ($mySelection.length) { mySelection.slideUp(); }

    // this is awesome
    // doOnce plug in by Paul Irish
    // great thing about it that it allows execute function during single chain
    jQuery.fn.doOnce = function(func) {
        this.length && func.apply(this);
        return this;
    }

    $('slider').doOnce(function() {
         console.log("start sliding")
     }).slideDown(500, function(){
         $(this)
             .find('h2')
       .text('Sliding complete')
       .doOnce(function(){
           console.log("sliding done")
       })
    });

Final thoughts

We have walked through what I consider are the essential steps towards organising javascript and jQuery code into well editable and extendable structure. Well done. These are quite simple techniques which definitely will make your usage of client side more effective. jQuery is not a programming language, but it deserves to be learned in the same way, there are a lot of useful functions which sometimes are overlooked.

I hope the code above was useful, happy coding!

comments powered by Disqus