Create a jQuery like chainable JavaScript toolbox specific to your project

"Global variables are evil" is what the JavaScript Guru Douglas Crockford says, as they are the source of unreliability and insecurity. How elegant your code would be if you wrap your entire project's code under a single global namespace?

[Did you know? The entire JavaScript code of Yahoo's website is accessible through a single global 'YAHOO' object!]

In this article, I would like to show how you can create a chainable JavaScript library(not a library exactly, but sort of a toolbox) specific to your project. The concept is nothing new., this is how libraries like jQuery are built. It is more about understanding certain design patterns in JavaScript.

The first thing to know is:

(function(){ 
    //your code here....
})(); 

This is nothing but a self executing anonymous function. All it does is, it simply executes whatever code you write inside it and disappears after that. The private variables declared inside this function are not exposed to the global scope, unless specifically attached to the window object.

The next thing to know is about Prototypal Inheritance in JavaScript. This is a huge topic in itself and the article assumes that the reader is familiar with this concept. The idea is, in our anonymous function, we would have a private function and prototype it with our custom functions.

This is how our JavaScript toolbox looks like: 

(function(){
    var mySpace=function(){
        return new PrivateSpace();
    }
 
    var PrivateSpace=function(){
    };    
 
    PrivateSpace.prototype={
        init:function(){
            console.log('init this:', this);
            return this;
        },
        ajax:function(){
            console.log('make ajax calls here');
            return this;
        },
        cache:function(){
            console.log('cache selectors here');
            return this;
        }
    }
    window.my$=mySpace();
})();

In the above code, "PrivateSpace" is a private function which is prototyped with our desired functions. "mySpace" is a function which returns a new instance of "PrivateSpace" when executed.

As said before, our anonymous function executes once and does not expose these functions to the outer world. To expose our functions under a namespace, we should add the instance of our "PrivateSpace" to a window level(global) object. This is exactly what the last line of the code does.

So, when we say

window.my$=mySpace(); 

we are executing "mySpace()", which returns a new instance of  "PrivateSpace()" function and assigning it to "my$", which is a window level object. So if you print my$ like:

console.log(my$);

, you would get all the functions present in the "PrivateSpace()" prototype. So you can call your functions like: my$.ajax(), my$.cache() etc.

Note that each function in "PrivateSpace()" returns "this". i.e., each function returns an instance of "PrivateSpace()" and hence you can chain your methods like:

my$.init().ajax();

That's it! Now we have our own JavaScript toolbox specific to our project! So no more global functions in our projects. As said, this is nothing new to the JavaScript world,  this pattern is what jQuery uses for chaining the methods.

I have faced few problems while opting for this pattern and posted them in StackOverflow. Folks there are kind to answer and hence this article. I'm no JS guru to say this is 100% perfect, but I have implemented this without any issues in a huge project.  You may refer Chapter 6 (Chaining) in  Pro JavaScript Design Patterns which explains about this jQuery like pattern.

Do you have better ideas? Please let me know.

Happy coding :)

When is AJAX an overkill for your ASP.NET-jQuery web applications? Part-2

In my previous article, I have discussed about few scenarios where AJAX can be an overkill for our web apps. I would like to add few more such scenarios in this post.

(4) Heavy dropdowns: 

A dropdown control enforces the user to select a value, preventing the entry of unwanted choices. This would make sense if a dropdown has limited options. But we tend to populate the dropdown with hundreds/thousands of options (probably this is the case with list of all cities in a country).

The scenario gets worse when we make an AJAX call to fill such huge dropdowns. There are many articles which show 'how to fill a dropdown using AJAX', but none of them stress on the limit of options. So, for a dropdown with 3000 options you are adding 3000 DOM elements, thereby degrading the performance of your page. Imagine 5 such dropdowns in a page!

Another scenario could be a row having a dropdown with 300 options, which repeats for ‘n’ times! These are unseen dangers which slow down your site.

Bottom line: Use dropdowns when you want to display limited(say ~50) elements. For anything more than this, use auto complete feature(You may choose between local/remote data based on number of records). The same rule holds good for cascading dropdowns. Keep your DOM as small as possible!

(5) Accordions: 

This is another beautiful UI technique almost similar to Tabs, the main difference being-tabs appear horizontally whereas accordions appear vertically. The problems faced in accordions are exactly the same ones which I have explained for tabs (please refer to my previous article).

Bottom line: If your page is too huge, do not fetch the entire DOM for building an accordion. On page load, build accordion structure and fetch the content of first pane only. On clicking the next header, remove markup from the previous pane and populate the current pane. This way, your page will always contain limited number of elements(though huge DOM manipulations can cause a little delay).

(6) Page load AJAX Calls/Multiple domains:

If you profile most of the web apps, they make a number of AJAX calls on page load for business functionality. e.g., If you are trying to fill 5 dropdowns on page load using AJAX calls, you are inviting performance problems.In most cases, we can get rid of such calls by injecting JavaScript objects into the page

Bottom line: If AJAX calls on page load are still unavoidable, instead of making multiple calls, make only a single call. In your web method, hit multiple controllers and fetch the desired response and club the responses using .NET’s Dictionary object. This way, you will reduce some network traffic.

You may also try to move some of your web services to different domains and access the data through JSONP.  The maximum number of parallel calls per domain in IE8/FF3 are 6. This means, by chance if you are making more than 6 AJAX calls, the remaining would be queued. By splitting your services across multiple domains, you can still make more than 6 calls in parallel!

On a closing note, I think I’m writing more of theoretical aspects without any code, but I don’t want to lose these experiences in the darkness of my memories. Following these simple guidelines helped me solve many performance bottlenecks in a large scale project. I feel this would be useful for developers at all levels while taking design decisions. Do let me know your views!

Follow me on twitter for live updates. Happy coding :)