Category: JavaScript

The Big Pipe – Faster Facebook

Posted by – July 20, 2010

Facebook is a big time killer. You can harvest farm without owning an inch of land, kill your buddies and still brag about it, save unknown species of zoo animals and poke any girl you know and she wont mind.
But Facebook is a case study for web developers like me. A typical Facebook page, depending on network and host, loads within 5 seconds. Facebook team has set this time to 2.5 seconds. Anything beyond 2.5 seconds is a big no no. For me it loads 19 CSS files, just one JS file, all in all a 50KB page w/out images. If you didnt pay attention to last line, it FB loads just one JS file and if you look at the byte size its just 10K file. Like I mentioned earlier Gzipped content is much lighter i.e. low byte size, it can be sent over network quickly. Facebook and every other website follows and compress the content they send over the network. But this is not all.
Before I move ahead, lets understand how a page is “rendered” in browser.

  • You send a request to FB servers.
  • FB server looks at your request and prepares a page, if you were logged in, it will send your profile page otherwise a nice login page. This job is done by PHP, MySQL, Apache and some in house tools developed by FB.
  • FB sends you back the page, the HTML
  • The browser reads or “parses” the HTML and finds out well it also needs CSS, images and JS and sends separate requests for these assets.

Now here is the tricky part. Browsers need all the possible assets that can affect the rendering of page and JS is one thing that can hide images, change CSS applied on an element, add text or can change the complete layout. So when browsers encounter a JS file they stop loading anything and concentrate only on JS. Till the time JS is not loaded and processed nothing else is done. This have been, more or less, same for nearly all the browsers till date. Web developers try to deceive browsers in many ways. The one way suggested by Yahoo! is to load JS at the bottom of page or develop the page in such a way that JS is loaded just before body tag is closed. This is not feasible in many cases. Say for example, on my webpage a menu appears in top header not in bottom of the page so it is rendered first and I need it to be active. There are way outs.

  • RequireJS
  • labJS
  • Load JS using AJAX
  • Create Script tag dynamically
  • Load scripts in iFrame
  • and others

Facebook employs some thing it calls a BigPipe. Interestingly FB divides its page into smaller chunks, named pagelets and every pagelet has its own JS associated with it. Have a look at following BigPipe fragment

<script> big_pipe.onPageletArrive({
 "id": "pagelet_nav_lite",
 "phase": 1,
 "is_last": false,
 "append": false,
 "display_dependency": [
 "pagelet_navigation"
 ],
 "bootloadable": {
 "editable-side-nav-js": [
 "CiNUi",
 "WTiBX",
 "Nahdv",
 "vstFf"
 ]
 },
 "css": [
 "p0tHf",
 "HOV0r",
 "FLbGk",
 "mWAGo",
 "e2Nmn"
 ],
 "js": [
 "CiNUi",
 "WTiBX",
 "k29le",
 "kJEXe",
 "5CZKw",
 "S4cYi",
 "3iRY2"
 ],
 "resource_map": {
 "e2Nmn": {
 "name": "css\/sprite\/autogen\/a2gtd9_duri.css",
 "type": "css",
 "nonblocking": 1,
 "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/z8ZLB\/hash\/40d4o2t0.css"
 },
 "vstFf": {
 "name": "js\/ui\/xhp\/page\/editable_side_nav.js",
 "type": "js",
 "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/z5QP6\/p\/hash\/eoj7km8p.js"
 }
 },
 "requires": [

 ],
 "provides": [

 ],
 "onload": [

 ],
 "onafterload": [

 ],
 "onpagecache": [

 ],
 "onafterpagecache": [

 ],
 "refresh_pagelets": [

 ],
 "invalidate_cache": [

 ],
 "content": {
 "pagelet_nav_lite": "HTML removed, view source your own FB profile page :-) "
 },
 "page_cache": true
})</script>

Further spying on the DOM using Firebug, I could see an iframe named “bootloader_iframe” which loads JS files.

BigPipe has really changed the way Facebook loads and works. Facebook is showing generosity and is sharing what it does. Unlike Yahoo! and Google, Facebook is not so much developer friendly and is not well known to share its knowledge. I hoping to see more documentation on BigPipe. Here is some info: http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919

The JSON object was formatted using JSONLint.

Drop down menus with jQuery

Posted by – March 18, 2009

After attempting sliding menus with jQuery I developed drop down menus using lists.

Here is the code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html>
  <head>
  <title>Drop Down Menus With jQuery</title>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript">
  function mainmenu(){
  $("#nav ul" ).css({display: "none"}); // Opera Fix
  $("#nav>li" ).hover(
function(){
$(this).find('ul:first').css({visibility: "visible",display: "none"}).show(400);
},
function(){
$(this).find('ul:first').css({visibility: "hidden"});
});
}
$(document).ready(function(){
mainmenu();
});
</script>
<style type="text/css">
#nav, #nav ul{
margin:0;
padding:0;
list-style-type:none;
list-style-position:outside;
position:relative;
}
#nav>li{
float:left;
position:relative;
}
#nav>li>a{
font-size:12px;
font-family: arial;
color:#000000;
padding:5px;
text-decoration:none;
border: 1px solid #ddd;
background:#eee;
}
#nav ul {
position:absolute;
dispay:none;
}
#nav a{
display:block;
}
#nav>li>ul>li>a{
font-size:12px;
font-family: arial;
color:#000000;
padding:3px;
text-decoration:none;
border: 1px solid #aaa;
background:#bbb;
}
</style>
</head>
<body>
<ul id="nav">
<li><a href="">HTML</a></li>
<li><a href="#" >CSS</a>
<ul>
<li><a href="#">CSS 1</a></li>
<li><a href="#">CSS 2</a></li>
<li><a href="#">CSS 3</a></li>
</ul>
</li>
<li><a href="#" >Javascript</a>
<ul>
<li><a href="#">Mootools</a></li>
<li><a href="#">Prototype</a></li>
<li><a href="#">jQuery</a></li>
<li><a href="#">Yahoo! UI</a></li>
<li><a href="#">Dojo</a></li>
<li><a href="#">Mochi Kit</a></li>
</ul>
</li>
</ul>
</body>
</html>

Sliding menus with Jquery

Posted by – February 26, 2009

I have been avoiding Jquery for quite some time. I was just turning myself blind to Jquery. Jaquery? What Jquery? :-/

Damn it! I have been spelling jQuery as Jquery. :D

I wanted some thing similar to accordion effect. There are tons of JavaScript frameworks offering this but I didnt want myself to be again copying huge/minified file/s and then reading hell lot of documentations figuring out how and why and ….

Phew #:-S

Now following is a snippet of code from my dear Kaddu. Obviously you will need jQuery.

<html>
<head><title>Tree</title>
<script type="text/javascript" language="javascript" src="js/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function(){
$('.level-1').hide();
$('.top').css('cursor','pointer').bind('click',viewList);
});
this.viewList = function (){
var id	 = $(this).attr('id');
var spId = id.split('_');
$('#ul_'+spId[1]).slideToggle();
}
</script>
</head>
<body>
<ul>
<li class="top" id="li_1"> 1
<ul class="level-1" id="ul_1"> <li>1.1</li>
<ol>
<li>1.1.1</li>
<li>1.1.2</li>
<li>1.1.3</li>
</ol>
</ul>
</li>
<li class="top" id="li_2"> 2
<ul class="level-1" id="ul_2"> <li>2.1</li>
<ol>
<li>2.1.1</li>
<li>2.1.2</li>
<li>2.1.3</li>
</ol>
</ul>
</li>
<li class="top" id="li_3"> 3
<ul class="level-1" id="ul_3"> <li>3.1</li>
<ol>
<li>3.1.1</li>
<li>3.1.2</li>
<li>3.1.3</li>
</ol>
</ul>
</li>
</ul>
</body>
</html>

Now, you can change lis to divs to spans to ps or what not. You just need IDs and thats it. You have a sliding menu. :-)

A small introduction to Object Oriented JavaScript

Posted by – December 10, 2008

Lately I have been studying Object Oriented Programming. I come from a background of small snippets, everything wrapped inside a small bulletproof function. Optimized to run as fast as possible. Things have changed from simple print function to more sophisticated print method or a system class (arghh!!!).
When I first wrote a piece of code for Linux I was told, everything is a file on a *nix system. So even if it is a directory/socket/drive/device you can treat it as a file and open it, read from it and write into it. So if you are going to do anything related to Linux tell yourself, everything is a file. Same in OOPS, tell your self everything is an object and it has some properties and some methods or in general have members. No functions. No variables. Everything is inherited or abstract or private or protected or…
JS, abbrevation for JavaScript, is an Object Based language totaly different from C, C++, Java or .NET and it is not truly Object Oriented. But still there are tweaks and hacks that allows one to model some concepts of OO. Object Based languages are also reffered as Prototype based languages. Prototypes as the word implies are not concrete objects and hence do not possess all the qualities, read methods and properties, of an object. Hence a string object in JavaScript may be or may not be same as string object in any other language.
All said and done. What all OO features can be implemented using JS?
a) we can define our own Objects.
b) we can extend predefined objects
c) we can inherit objects, really?? “Yes Sire”.
d) we can simulate classes, remember simulation is far away from reality.
Time to jump into code. Do it yourself.

/*
Just a quick hack ;-)
*/
function d(str){
	document.write(str);
}

{//Brace added just to limit everything in to local scope
/*
a constructor
*/
var bikeSimple = function(){ }
/*
Or
*/
function simpleBike(){ }

var pulsor = new bikeSimple;
var splendor = new simpleBike();

}//Brace added just to limit everything in to local scope

{//Brace added just to limit everything in to local scope
/*
Initialise an object
*/
/*
a constructor
*/
var bikeSimple = function(modelName, cc, mileage){
	/*
	Private members.
	*/
	var modelName = modelName;
	var cc = cc;
	var mileage = mileage;
	function canBeDriven(){
		return true;
	}
	/*
	Public members
	*/
	this.color = 'Black';
	/*
	*/
	this.sounds = function(){
		d('Vroom!');
	}
}
var pulsor = new bikeSimple('Pulsor DTSi', '150/180/220', '40-50');
/*
Or even the Object Initializer way.
*/
var cruiserBike = {modelName:'Bullet 350', cc:'350', mileage:'45-50' }
}//Brace added just to limit everything in to local scope

{//Brace added just to limit everything in to local scope
/*
Set/Get/Delete properties using methods
*/
/*
a constructor
*/
var bike = function(){
	this.setInfo = function(modelName, cc, mileage){
		this.modelName = modelName;
		this.cc = cc;
		this.mileage = mileage;
	}
	this.getInfo = function(){
		d('Model: ' + this.modelName + 'CC: ' + this.cc + 'Mileage:' + this.mileage );
	}
	this.vroomProperty = 'vroom!!!';
	this.vroom = function(nTimes){
		nTimes = (nTimes < 0 ? 1 : nTimes);
		for(i=0;i
			d(this.modelName + ' says ' +this.vroomProperty);
		}
	}
}
/*
Sample (and simple too!) invocation
*/
var pulsor = new bike;
pulsor.setInfo('Pulsor DTSi', '150/180/220', '40-50');
pulsor.getInfo();
pulsor.vroom(5);
/*
Or even this also works, not the OO way to do things
*/
function cruiserBike(modelName, cc, mileage){
	this.setInfo = function(modelName, cc, mileage){
		this.modelName = modelName;
		this.cc = cc;
		this.mileage = mileage;
	}
}
var bullet = new cruiserBike;
bullet.setInfo('Bullet 350+', '350', '40-45');
bullet.getInfo = function(){
		d('Model: ' + this.modelName + 'CC: ' + this.cc + 'Mileage:' + this.mileage);
	}
bullet.getInfo();
/*
But wait...
*/
var thunderbird = new cruiserBike;
thunderbird.setInfo('Thunderbird', '350', '40-45');
/*
This will throw an error
thunderbird.getInfo();
*/
/*
That vroom property is stupid, delete the property.
*/
delete pulsor.vroomProperty;
pulsor.vroom(5);
/*
Can I do this?
Apparently not this way.
*/
delete pulsor.vroom();
pulsor.vroom(3);

/*
...but this way, look no parenthesis
*/
delete pulsor.vroom;
pulsor.vroom(3);

/*
And the Object Initializer way. This led to JSON.
*/
var ducatiMatrix = {setInfo: function(modelName, cc, mileage){
		this.modelName = modelName;
		this.cc = cc;
		this.mileage = mileage;
	},
	getInfo:function(){
			d('Model: ' + this.modelName + 'CC: ' + this.cc + 'Mileage:' + this.mileage);
		}
	}
ducatiMatrix.getInfo();
}//Brace added just to limit everything in to local scope

{//Brace added just to limit everything in to local scope
/*
The power of prototyping
*/
/*
a constructor
*/
var bike = function(){}
bike.prototype.setInfo = function(modelName, cc, mileage){
	this.modelName = modelName;
	this.cc = cc;
	this.mileage = mileage;
}
bike.prototype.getInfo = function(){
	d('Model: ' + this.modelName + 'CC: ' + this.cc + 'Mileage:' + this.mileage );
}
/*
Sample (and simple too!) invocation, again!
*/
var pulsor = new bike;
pulsor.setInfo('Pulsor DTSi', '150/180/220', '40-50');
pulsor.getInfo();
/*
...& the following
*/
Date.prototype.myBirthDay = function(){
	return('My birthday falls on 3rd December, you can gift me iPods, Zunes, Toughbook, high speed data line..');
}
/*
Chainining the object, and look the Date is a native object and I haveadded my own method to it!
*/
d((new Date).myBirthDay());
}//Brace added just to limit everything in to local scope