Lazy loading for Javascript

Posted on September 25, 2011
by

In a previous post, I was discussing how to lazy load a Facebook widget, so that it loads only when really needed. I have put my thoughts further, and come up with a general way to lazy load any kind of JavaScript snippet.

I always take for example the Facebook widgets, which are always very heavy and load many files (include JS, CSS and images).If that widget is not in the viewport when your visitor loads your page at the beginning, and if it’s visible only after he scrolls, then you can tweak the performances of your page by lazy loading that widget. Note that it works for any kind of JavaScript snippet that would have a visible effect only after the user scrolls your page down.

In this post, I’ll introduce my jQuery plugin and show you a demo of how it works, but I’m not going to go very deep into the interior mechanisms (for that, see the Google Code page).

jQuery lazy loading JS

Example: how to lazy load the Facebook Like Box

Let’s say you have a Facebook Like Box in your page, and it’s located far in the page, so far that the user needs to scroll before seeing it on his screen. The code given by Facebook is that one:

<div id="fb-root"></div>
 
<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";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
 
<div class="fb-like-box" data-href="http://www.facebook.com/platform" data-width="292" data-show-faces="true" data-stream="false" data-header="false"></div>

This script will of course load the widget right away when the page initially loads. Let’s say the placeholder (the fb-like-box div) is located far and you want to lazy load it only once the user scrolled down enough to have it in viewport. The only thing you need to change is this:

$('.fb-like-box').lazyloadjs(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";
fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');

Basically, you just have to surround the JavaScript code by this
$('.fb-like-box').lazyloadjs( ... );

The selector (.fb-like-box) must be the placeholder of your widget, which is a div in our case. This placeholder will be watched until it gets into the viewport. The lazyloadjs() function accepts only one argument, which must be a pointer to a function (either a named function or an anonymous function would do). Once the placeholder gets into the viewport, the function you give in parameter will be executed.

Actually, in this special case of the Facebook Like Box, we need to adapt the given snippet to the following:

$('.fb-like-box').lazyloadjs(function() {
var d = document;
var s = 'script';
var id = 'facebook-jssdk';
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";
fjs.parentNode.insertBefore(js, fjs);
});

Why? Because the previous construction function(){}(); was calling the function right away after its definition and returning its result, instead of returning a pointer to that function. And we don’t want that function to be executed right away, we absolutely want it to be executed only when needed, later.

Second point, my plugin doesn’t allow you to use parameters in your function, so you need to make special adjustments for that too.

And voilà. Most of the time you will probably not need to modify your JavaScript snippet to lazy load it, but bare in mind that you MUST give a reference to a function to lazyloadjs().

Live example

The Facebook widget below only loaded when you scrolled down enough to see it in your viewport 😉 Don’t believe me? Go back up, refresh the page and start to scroll down again…

Download

You can download the latest source or the minified version.

If you see bugs or want to help me improving it, you can leave a comment or join the Google Code project page: jquery-lazyloadjs

About the author

Cyril Mazur is a serial web entrepreneur with experience in various fields: online dating, forex & finance, blogging, online advertising... who enjoys building things that people like to use.

13 comments