After listening to the latest Practical Webdesign Magazine podcast (I listen to every one of them as well as the Boagworld podcast, both being great podcasts), I felt the urge to write this post :). When you include many third party things in your webpage, the loading of it can be slowed down considerably if the client doesn’t have a good connection or the given service has outages. The solution I came up with is to delay the inclusion of the content until the webpage (or at least the part loading from your server) has finished loading. To accomplish this I’ve created the little javascript below. What it does is to schedule a given function to be executed a given number of milliseconds after the page has been loaded. If you set this low (the default is 100 milliseconds for example), the users won’t notice an interruption in the loading (if the other services that you rely on can deliver content fast enough) or at least will see the parts of your page which is loaded from your server until the other parts load (if they have a slow connection to the third party source). To use this, use the following type of call: delayedLoader.scheduleAfterLoad(function() { alert("Hello World!"); });
.
An other feature of this script is that it simplifies the cases when you have to include HTML from third party sites (an IFRAME for example). To use this feature create a placeholder div or span in which you should include the temporary content (the content which should be displayed while the third party content is loading), give it a class of "to_replace" and immediately after create a comment in which you should include the text witch which the temporary content should be replaced. Probably looking at the example below this becomes much clearer than after reading my babbling.
-
<div class=“to_replace”>This needs to be replaced!</div>
-
<!– This is the <em>replacement</em> –>
The source code:
-
var delayedLoader = {
-
addEvent : function (obj, evType, fn) {
-
//taken from: http://www.scottandrew.com/weblog/articles/cbs-events
-
if (obj.addEventListener){
-
obj.addEventListener(evType, fn, false);
-
return true;
-
} else if (obj.attachEvent){
-
var r = obj.attachEvent(“on”+evType, fn);
-
return r;
-
} else {
-
return false;
-
}
-
},
-
-
//schedules a given function to be invoked a given number of miliseconds
-
//after the loading of the document has finshed. the default number of
-
//miliseconds is 100
-
scheduleAfterLoad : function (fn, msecs) {
-
if (msecs <= 0) msecs = 100;
-
this.addEvent(window, ‘load’, function() { setTimeout(fn, msecs); });
-
},
-
-
replaceElements : function () {
-
var replaceElementArray = function (to_process) {
-
for (var i = 0; i < to_process.length; i++) {
-
if (to_process[i].className.indexOf(‘to_replace’) > -1) {
-
var element = to_process[i];
-
while (null != element && 8 != element.nodeType) element = element.nextSibling;
-
if (null != element && 8 == element.nodeType)
-
to_process[i].innerHTML = element.nodeValue;
-
}
-
}
-
};
-
-
//process divs and spans
-
var to_process = document.getElementsByTagName(‘div’);
-
replaceElementArray(to_process);
-
to_process = document.getElementsByTagName(‘span’);
-
replaceElementArray(to_process);
-
},
-
-
init : function () {
-
this.scheduleAfterLoad(this.replaceElements);
-
return this;
-
}
-
}.init();
-
There is a potential problem with all this: the user might not have javascript enabled. This could be mitigated by repeating the content in a noscript tag (that was my original plan to use the content of the noscript tag to replace the content of the parent), however I’m pretty sure (although not 100%) that the user agent (the browser) would still load the stuff, event though it is invisible and slow the loading of the site down.