If you use social widgets on your web pages, you must be aware of the extra kilobytes of data your visitors are going to load for this, and how it’s going to affect the loading time of your pages. It can be difficult to figure the weight of those widgets, but sometimes they’re worth considering them.
You can use Firefox and the plugin YSlow to measure how those social widgets overweight your pages (see total size of the page, loading time, and number of external JS/CSS/image files loaded).
In this post, I will consider the case of the Facebook Like Box, which is a quite fat widget actually (almost 200kB of data amongst 6 external JS scripts, 4 CSS sheets, 2 CSS image sprites and as much images as there are fans of your page) and how I can manage to load it ONLY IF NEEDED.
Defer loading of the widget
First, it’s good to defer the loading of the widget so that it loads when the rest of the page is already loaded (because the page itself should have higher priority on the optional widgets). To do so, we will use jQuery, add this piece of code anywhere on your page:
$(document).ready(function() {
$('#facebookHolder').append('<div id="fb-root"></div>');
$('#facebookHolder').append('<fb:like-box href="http://www.facebook.com/forexagone" width="300" show_faces="true" stream="false" header="false"></fb:like-box>');
jQuery.getScript('http://connect.facebook.net/en_US/all.js#xfbml=1', function() {
FB.init({status: true, cookie: true, xfbml: true});
});
});
You also need a place holder somewhere on your page to hold the widget, such as:
<div id="facebookHolder"></div>
Now, the widget will start loading only ONCE the page itself is loaded.
Lazy load the widget
It can happen that your social widget is embedded in a long page and the user needs to scroll to see it on his screen. Then, there is obviously no interest in loading 200 extra kilobytes of data as long as the widget is not in the browser’s viewport (is not visible on the screen). That’s what we call lazy loading: we only load what we need to load. You’ve probably seen this technique on websites such as TechCrunch, that load the images on the page as you are scrolling it down (see the jquery plugin Lazy Load by Mika Tuupola — deprecated though, since it’s not supported anymore for latest browsers). Mika also wrote the Viewport selectors for jQuery that I’m going to use for lazy loading my social widget.
So the idea is to not load the social widget when your page is loading, and if the user ever happens to scroll down enough to make the social widget placeholder to appear in the browser’s viewport, then we eventually load the widget.
Here is the JavaScript you need to load (but well, it’s very likely that you already use jQuery, isn’t it?)
<script src="jquery.js"></script>
<script src="jquery.viewport.js"></script>
Here is the HTML code for the placeholder of your social widget:
<div id="facebookHolder"></div>
And here is the JavaScript code to defer and lazy load the widget:
/**
* check if facebookHolder is in viewport, and then load Like Box widget
*/
$(document).ready(function() {
function checkScrollingForWidget(event) {
$('#facebookHolder:in-viewport').each(function() {
$('#facebookHolder').append('<div id="fb-root"></div>');
$('#facebookHolder').append('<fb:like-box href="http://www.facebook.com/forexagone" width="300" show_faces="true" stream="false" header="false"></fb:like-box>');
jQuery.getScript('http://connect.facebook.net/en_US/all.js#xfbml=1', function() {
FB.init({status: true, cookie: true, xfbml: true});
});
$(window).unbind('scroll', checkScrollingForWidget);
}
$(window).bind('scroll', checkScrollingForWidget);
});
This works well for all the Facebook widgets. You will have to adapt the code to the other social widgets you’re using, but the idea remains the same.
Practical example
In Forexagone.com (website I co-founded), we embed a Facebook Like Box at the bottom of the forum page. It’s a long page, and not everybody is likely to scroll down enough and see the widget on the screen. Therefore, I applied the lazy loading behaviour to the Facebook Like Box widget, and I was very happy to see that I improved by a factor 2 the loading time of my page, and decreased its total size by 200kB.

That will save some time and bandwidth. I think Google (and the visitors) will appreciate
Permalink
Nice code, thanks!
I'm using it with Wordpress and added the code to the sidebar file of the theme. But although Wordpress includes a minified version of Jquery in the header*, it doesn't work unless I add [script src="http://code.jquery.com/jquery-1.6.1.js"][/script] right above your code (in the sidebar).
Any idea why this is?
* [script type='text/javascript' src='http://www.myblog.com/wp-includes/js/jquery/jquery.js?ver=1.6.1'][/script]
Permalink
You haven't been put to the trash, I was just away from the Internet for one week recently (Burning Man YEY).
Can you check if putting "$(function(){" instead of "$(document).ready(function() {" solves the problem? I'm afraid that the Javascript code for the lazyloading feature is executed BEFORE the jQuery library is loaded.
Also, I tested my code with jQuery 1.4.4, so maybe it's a problem related to jQuery's version...
Regards.
Permalink
Permalink
Uncaught SyntaxError: Unexpected identifier.
Here: $(window).bind('scroll', checkScrollOnForumPage);
¿Where is checkScrollOnForumPage function?
Permalink
This is my mistake, the correct function name is well "checkScrollingForWidget" and not "checkScrollOnForumPage" (wrong copy/paste from my testing environment). I corrected the code example. Thanks!
Permalink
many thanks for sharing this great information.
I've just used it on a site and it works like a charm.
Permalink
Le code ne fonctionne pas du tout avec mon site web. Il ne se passe rien. Existe-il un moyen en utilisant le code facebook mais en html5?
A noter que mon site est fait avec joomla 2.5
Permalink
Permalink
Alors oui la console me donne ce message:
missing ) after argument list
$(window).bind('scroll', checkScrollingForWidget);
Avec une petite fleche qui pointe sur le "$"
Pour le faire en HTML5, malheuresement je ne connais pas suffisament le javascript. :-(
Merci pour tout
Permalink
Permalink
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="language; ?>" lang="language; ?>" dir="direction; ?>" >
<link rel="stylesheet" href="baseurl ?>/templates/template ?>/css/style.css" type="text/css">
/**
* check if facebookHolder is in viewport, and then load Like Box widget
*/
$(document).ready(function() {
function checkScrollingForWidget(event) {
$('#facebookHolder:in-viewport').each(function() {
$('#facebookHolder').append('');
$('#facebookHolder').append('');
jQuery.getScript('http://connect.facebook.net/en_US/all.js#xfbml=1', function() {
FB.init({status: true, cookie: true, xfbml: true});
});
$(window).unbind('scroll', checkScrollingForWidget);
}
$(window).bind('scroll', checkScrollingForWidget);
});
<a href="http://www.destockforum.com" rel="nofollow"> </a>
id == 0){ ?>
Copyright &copy 2012 Destockforum. Tous droits réservés.
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-31444402-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
par contre bizarrement en utilisant le code de forexagone cela fonctionne. Tu peux jeter un oeil sur mon site web: destockforum.com
merci de ton aide et a bientot
Permalink
Permalink
J'ai effectivement trouver une accolade et une parenthèse manquante, mais malheureusement ça ne fonctionne toujours pas. Peux être un conflit javascript.
De toute manière je vais suivre ton conseil et utiliser le code de forexagone. Celui-ci fonctionne avec moi. ;-)
Permalink