Friday, June 28, 2013

Javascript - Understanding BackboneJS And Client Side MVC

Here, I am going to explore BackboneJS. Since I am newbie to client-side MVC,  it seems to be very hard to understand the concepts of BackboneJS. This was making me frustrated initially. So that, I decided to go back to some traditional approach and do step by step analysis toward modern approaches.

In following, I have done some experiments and I expects you to do same. So that you can enjoy the real power of "Javascript". The following content is little bit different from your usual blog. So before start to read this blog post, I recommend you to download the code base from "Github"   and you have to install latest chrome with developer tool.


Now I am taking simple concept to explore these things.  So I have designed simple "Polling System" that looks like as follows.

To easy understand, I am giving little introduction about this image. Here I have listed out some computer programming languages and given a button to vote for your favorite language. And the middle column "Count" shows that how many times, you clicked the "Vote" button.

Approach 1:

Let's take traditional approach, in this I have written a function named as "updatePollCount" to vote increase count and run that function on every button click event. To run the function, I have added a "onclick" attribute within all button tags. The code, written in index.html as follows,

[Path: http://…/UnderstandingBackbone/TraditionalJavascriptApproachWithGlobalScope/index.html]

And the code written in counter.js is as follows,
[Path: http://…/UnderstandingBackbone/TraditionalJavascriptApproachWithGlobalScope/js/counter.js]

The Inline Binding(ie. Specifying event and the handler function) is pollute the markup. It affects readability. If you want to add more event  to a particular HTML element, then you have to mention all of the event and respective handler function like as follows,
<div onmouseclick="handler1()" onmouseover="handler2()" ></div>

This inline binding doesn't give any meaning or appearance changes to end user, rather than give instruction to "Javascript Engine".

Oops… I forgot to discuss one important thing. There is a biggest performance issue hidden in this. To  write inline binding code, you have to define all the function as global or you have to attach the function in global object which is called as "window". Due to global scope, the Javascript Engine lookup all the keys to locate and run respective function on each and every user interaction. This will lead to severe CPU consumption and result is browser hang-ups. So we can't imagine about development  of dynamic websites where frequent DOM manipulation happen based on user interactions (like Facebook) by using this traditional approach. To experiment this, I have modified the existing counter.js file and created as a separate codebase. The modified counter.js looks as follows,

[Path: http://… /UnderstandingBackbone/TraditionalJavascriptApproachWithoutGlobalScope/js/counter.js]

To execute experiment, follow the image shown in below,

  Left Hand Side: http://…/UnderstandingBackbone/TraditionalJavascriptApproachWithGlobalScope
  Right Hand Side: http://… /UnderstandingBackbone/TraditionalJavascriptApproachWithoutGlobalScope
To overcome traditional approach problems, the community introduced OOJS(Object Oriented Javascript). Since I am talking about dynamic websites, there are more powerful Javascript libraries and frameworks like jQuery , YUI, PrototypeJs and more on handling dynamic content in web pages. I have enough experience in jQuery, So that I have taken jQuery to continue further analysis and created separate codebase.

Approach 2:

I have discussed two problems above. First one is "Inline Binding" and the second one is "Javascript Engine's Performance".  Let's take "Inline Binding", jQuery is provided rich selector method.  By using this jQuery selectors, we can completely remove the inline binding codes. So I have re-implemented "Polling System" by using jQuery. I have modified my HTML and counter.js file as follows,

[Path: http://…/UnderstandingBackbone/JQueryApproachWithoutGlobalScope/index.html]

And counter.js is re-implemented in jQuery as follows,

[Path: http://…/UnderstandingBackbone/JQueryApproachWithoutGlobalScope/js/counter.js]
Now the HTML code looks good, there is no unwanted attributes present. My first problem is completely resolved. Let's see "Javascript Engine's Performance" in terms of "window" object loads, jQuery is more powerful on keeping "window" object as lighter. In above, You can see the jQuery code written in counter.js file. In that, I have defined the function "updatePollCount" within scope of another function called as "onAfterPageLoad". So that, the function "updatePollCount" is divided from "window" object. Even "window" object doesn't hold the function "updatePollCount", the Polling System is working well.
To experiment this, follow the image shown in below,
  Left Hand Side: http://… /UnderstandingBackbone/TraditionalJavascriptApproachWithoutGlobalScope
  Right Hand Side: http://…/UnderstandingBackbone/JQueryApproachWithoutGlobalScope

Here, I have achieved everything what I want. Really I don't need "BackboneJS". I have read articles, most of them simply says that "BackboneJS" more powerful on developing heavy-weight client side Javascript applications. Some other articles explain well about how to use "BackboneJS". But my simple question is, WHY SHOULD I USE BACKBONEJS TO HANDLE MORE DYNAMIC PAGES?

Approach 3:

Since I am talking about dynamic web pages, and to find answer of the above asked question, I am going to add a little dynamic manipulation in the "Polling System". Let's assume, you can allow only three nominees in the "Polling System" and allow the user to select their favorite nominee at a time. And after the winner is selected, then you can allow another three of nominees into the "Polling System". Here once first winner is selected, adding another set in the "Polling System" is going to be happen dynamically. I have implemented this by using jQuery and BackboneJS in separate code base. And I have compared them based on their execution time.

The jQuery implementation of dynamic handling is as follows,
[Path: http://…/UnderstandingBackbone/JQueryApproachOnDynamicHandling/js/counter.js]

The BackoneJS implementation of dynamic handling is as follows,
[Path: http://…/UnderstandingBackbone/BackboneJSApproachOnDynamicHandling/js/counter.js]

To execute the experiment, follow the images shown in below,
Left Hand Side: http://…/UnderstandingBackbone/JQueryApproachOnDynamicHandling
Right Hand Side: http://…/UnderstandingBackbone/BackboneJSApproachOnDynamicHandling

Note:  About Chrome Developer Tool's Profiles
1. "Self" Column indicates time, spend on executing the function which is shown under function column.
2. "Total" Column indicates cumulative time, spend on executing the function and the functions which are presented in current function's call stack.

In above comparison image, You can ignore (idle) and (garbage collector) times and remaining times are indicating time spend by CPU while execution. In this experiment, the code implemented in jQuery has taken (19 + 21 + 0 +  1 + 1 + 2) = 44ms. And the code implemented in BackboneJS has taken (9 + 14) = 23ms. This is clearly showing that BackboneJs is faster than jQuery. I repeated the experiment many more times. I saw that BackboneJs always consumes less CPU time.

Now I am happy to use BackboneJS on handling dynamic web pages. Guys, I hope that you all enjoyed. 

Thanks for spending time to read this blog post...

Note: Please write your queries and suggestion as comment

No comments:

Post a Comment