RSS

Lessons to learn from facebook like button widget for asynchronously loading javascript files

29 Jul

Consider how we load external javascript files in our web pages.

<script type="text/javascript" src="http://mysite.com/scripts/myscript.js"></script>

Normally while this JavaScript file is downloading other loading other components on the page get blocked. Need a proof? well using firebug’s Net tab you can easily see this effect.

The way facebook developers have handled this situation in their facebook like button widget script is really worth to note.

Consider following code which is what their like button widget code looks like.


<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=401009919956151";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

If you look closely at this script what actually it does is creating the script tag dynamically in the page.If you follow this technique what you are essentially  doing is you are downloading the script file asynchronously without a blocking call to a external JavaScript file. Real magic behind this is when you create script tag dynamically you are not blocking browser rendering of the rest of the components while the script file is being downloaded. Browser will create another thread and starts downloading the file.
Why they have used

fjs.parentNode.insertBefore(js, fjs);

instead of trivial version like this

(document.head || document.getElementsByTagName('head')[0]).appendChild(js);

The reasons might be facebook developers don’t control the markup of the host page where this script will be included. What if the host page doesn’t have a head element. Yes it might be not valid markup but many browsers create missing tags and create head tag if host page does not have one. So there might be rare situations that dependance of head tag script might break. Then comes the question why you cannot do this….

document.body.appendChild(js);

Same story as head, almost all browsers create body tag automatically if your document does not contain one.

fjs.parentNode.insertBefore(js, fjs);

in above code what facebook developers have done is find the first script tag in the host page and create facebook script element before the first script tag since any one who uses facebook like widget must have at least one script tag(even if host page of the facebook widget code don’t have a head  or body tags) which is very clever thinking :).

But you may have another function or more script that need to be run when your script file has downloaded. In those situations you could use code like these

 
js.onload = function () {
/*do your magic here*/
} 
Advertisements
 
Leave a comment

Posted by on July 29, 2012 in Javascript

 

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: