I know this is an old topic but this may come in handy for others with the same problem.
If you have tons of facebook widgets for example one per result on a search results page and you want them all to render yet don't want to hit your user with tons of connections at the same time you can use this to throttle the rendering.
Code:
var fbThrottle = (function () {
var settings = {
// how many widgets can be rendering at any one time
simultaneousRenders: 3,
// how often to add a new widget to the queue, if the queue is not full
renderInterval: 100,
// max amount of time we will wait until marking a widget as rendered
// this is in place so as not to block the queue if a widget takes too long
maxRenderWaitFailsafe: 5000,
// how long to wait before calling the callback function (if supplied)
// after a widget finishes rendering. can be used to say set the area visible after render if you had it hidden to prevent fout.
callbackDelay: 250,
};
var fbWidgets = [];
var activeRenders = 0;
setInterval(function () {
if (fbWidgets.length == 0)
return;
if (!window.FB)
return;
if (activeRenders < settings.simultaneousRenders) {
var obj = fbWidgets.shift();
if (typeof obj !== 'undefined') {
activeRenders++;
(function () {
var currentRenderDone = false;
setTimeout(function () {
if (!currentRenderDone) {
activeRenders--;
currentRenderDone = true;
}
}, settings.maxRenderWaitFailsafe);
window.FB.XFBML.parse(obj.widget, function () {
if (!currentRenderDone) {
activeRenders--;
currentRenderDone = true;
}
if (typeof obj.callback === 'function') {
setTimeout(function () {
obj.callback();
}, settings.callbackDelay);
}
});
})();
}
}
}, settings.renderInterval);
return {
add: function (widget, callback, top) {
if (typeof widget === 'undefined')
return;
if (typeof widget === 'string')
widget = document.getElementById(widget);
var obj = {
widget: widget,
callback: callback
};
if (top)
fbWidgets.unshift(obj);
else {
fbWidgets.push(obj);
}
},
};
})();
Usage:
You can add the elements to the throttle all at once, or have sonar pass them in as they become visible.
// add in the element to be rendered to the end of the list
fbThrottle.add(element);
// or you can pass in just the id
fbThrottle.add("idOfElement");
// you can pass in a callback as well
fbThrottle.add(element, function(){
// do something after
});
// you can add an element to the top of the list by setting the third parameter to true
fbThrottle.add(element, callback, true);
As Jakobud mentioned it is best to turn off the fb js api's automatic rendering of the widgets by turning xfbml off in your FB.init
window.FB.init({
xfbml: false
});