Tag Archives: javascript

Optimizing DOM manipulations

Often there arises a need to make changes to DOM structure, be it adding, removing or relocating elements. And there are so many ways to do them! So today I was just curious to know how fast is one approach than the other. I’ll use two ways and try to show you how long they took to run! And believe me you’ll be amazed!

  1. Live addition to DOM structure using jQuery’s appendTo()
    for(var i=0; i<10000; i++) {
      //assuming an ol element with id = ol1 is present in our DOM
      $('<li>I am an ordinary list element.</li>').appendTo('#ol1');
    }
    
  2. Adding in one go using jQuery’s .html()
    var domString = "";
    for(var i=0; i<10000; i++) {
      //creating a string of html
      domString += '<li>I am an ordinary list element.</li>';
    }
    //adding it in one go
    $('#ol2').html(domString);
    

The Verdict

First approach of adding elements to live DOM tree took ~1296 milliseconds and the second approach to concatenate a string of elements and then add it in one go took just 41 milliseconds.

So the second approach is 30 times faster than the first approach which does additions to a live DOM!

You can check the code on jsfiddle
http://jsfiddle.net/ankeetmaini/fpTXJ/2/

And you can check this live sample, which demonstrates both the approaches and gives the milliseconds elapsed in each approach! This is cool!
http://jsfiddle.net/ankeetmaini/fpTXJ/2/embedded/result/

Writing Modular JavaScript!

Of all the ways in which you can write JavaScript, modular style is one of the most intriguing. It allows you to make your data and methods private. It does it by using closures. Module pattern thrives on the fact that your App can be made more manageable by dividing it into modules. And successfully, hiding, abstracting the detailed parts under those modules, while leaving simple interfaces open to carry out the tasks!

In JavaScript per se, everything is global. So if you’re used to write your code in functions, you would realize that everything you write is global, and can easily be encroached upon by some other code in other files. What if you depended on a global variable’s value, only to have it changed by some other non-suspecting JavaScript code. As a best practice we should always keep our global footprint down to a minimum.

Let’s see module design pattern in action!

var MyModule = (function(){
    var privateVariable;
    var privateMethod = function() {
    };
    return {
        publicMethod: function(){
            //can call private method here
            privateMethod();
        }
   };
}());

That is the simplest module. Anything which is inside return block, is accessible from outside. If you type the above code in console, we’ll see that the privateVariable, and privateMethod isn’t available to us under the global variable MyModule only publicMethod is available. MyModule Building on the same concept we’ll now make another app that is more like a real world app which uses jQuery too. Let’s make an AppleApp.

This app will have a private variable apples which we’ll be decrementing and incrementing by two private methods eatApple() and buyApples(). We will also define another method called viewApples(), this will return us the private variable apples!

We’ll bind methods to buttons like we normally do in a real web application, and this we’ll do in a private method called bindDOMEvents().

var AppleApp = (function ($) {
    //private variables and methods
    var apples = 0;
	var eatApple = function () {
        if (apples > 0) {
            apples--;
        } else {
            alert("Cannot eat. No stock. Buy first.");
        }
		$(document).trigger("ateApple.appleApp");
    };
	var buyApples = function (newApples) {
        apples += parseInt(newApples, 10);
		$(document).trigger("addedApples.appleApp");
    };
	var bindDOMEvents = function() {
		//on button clicks
		$('input#eatApple').on("click", function(){
			eatApple();
		});
		$('input#buyApples').on("click";, function(){
			var num = $('#numberOfApples').val();
			buyApples(num);
		});
		//to display current value of apples
		$(document).on("addedApples.appleApp ateApple.appleApp", function(){
			$('span.box').text(apples);
		});
		//to change the label of button
		$('#numberOfApples').on("change", function(){
			$('input#buyApples').attr('value', 'buyApples('+$(this).val()+')');
		});
		
	};
	
	//our own document.ready function
	(function(){
		$('span.box').text(apples);
		$('input#buyApples').attr('value', 'buyApples('+$('#numberOfApples').val()+')');
		bindDOMEvents();
	}());
    
	//public methods
	return {
		viewApples: function() {
			return apples;
		}
    };
}(jQuery));

There’s a lot going on with the code above. Firstly, we pass jQuery object to our module’s anonymous function as an argument, so that we can access it locally without any conflicts. Then we define apples, eatApple(), buyApples(), bindDOMEvents().

Then we create another self-invoking function closure which executes immediately and we called the above defined bindDOMEvents(). This works because we include our script just before the ending of the body tag, and by then the whole DOM structure is made ready by the browser. Else we would have to use jQuery’s document.ready method.

//our own document.ready function
	(function(){
		$('span.box').text(apples);
		$('input#buyApples').attr('value', 'buyApples('+$('#numberOfApples').val()+')');
		bindDOMEvents();
	}());

And after that we finally have the return block, which contains a public method. It’s the only method which can be called from outside, via AppleApp.viewApples(). I’ve even highlighted the relevant parts!

You can access, copy, edit, and run the code from the following jsfiddle link.

http://jsfiddle.net/ankeetmaini/Ang8x/

And this is the AppleApp in fullscreen!

http://jsfiddle.net/ankeetmaini/Ang8x/embedded/result/