The Fastest Site on The Block Blog
Don’t Let Ads, Widgets, and other External JavaScript Slow You Down
Why are JavaScript calls a problem
As the web evolves and more and more sites move towards being “web 2.0″ applications, JavaScript is used more and in greater volume. This is a major problem because most browsers including IE and Firefox block loading and rendering elements below script tags, until the script has been downloaded and executed. Steve Sounders wrote a killer blog about preventing blocking of JavaScript calls, but he didn’t address the situation where scripts call document.write() to inject HTML immediately below the script tag. This test page shows that using the Script DOM Element technique causes document.write calls from within the external script to output html at undesirable places. This blog introduces a new technique called “postload dummy replacement”, that specifically addresses loading scripts that rely on document.write().
Who uses External JavaScript
You can pick up external JavaScript from many different sources. It is commonly used by ad agencies, widgets, and third party embeddable objects. For instance, a VeriSign logo that let’s people know your site is secure and a Skype button I recently picked up to allow visitors to see when I’m online and skype me, both use externally loaded JavaScript that rely on document.write(). Ad Agencies can even nest external JavaScript within external JavaScript leaving you at the mercy of multiple third party providers.
Fighting JavaScript with JavaScript
Ever heard the expression fight fire with fire. Well, for this web optimization technique, we will be fighting JavaScript with JavaScript. This technique I call “postload dummy replacement” allows you to load these JavaScript files inside a hidden DIV at the very bottom of your web page, then use JavaScript to swap out the the contents created by document.write calls inside the hidden DIV with contents of a placeholder element where the JavaScript was originally located.
GetSnappy.com Ad Delay
Ad Delay, is a JavaScript module I’ve written that implements “postload dummy replacement”. I’ll introduce you to Ad Delay, by walking through an example. I’ll use the Skype button mentioned above in my example. We’ll start by creating a placeholder DIV and set it’s id to “skypePlaceholder”.
<div><div id="skypeUsPlaceholder"></div></div>
While “skypeUsPlaceholder” is empty, you are free to implement placeholders however you please, and there contents will be replaced by the call to adDelay.swapOut() mentioned in the last step. You might want to set a height and width for the placeholder, to prevent the page from “jumping” when the swapOut occurs, and you could even include an Ajax loading icon, such as the ones available from http://www.ajaxload.info/.
Now let’s jump down to the bottom of our web page, immediately before the closing </body> tag. Here we will include the JavaScript tag within a “hidden” dummy DIV. We will assign this DIV the id “skypeDummy”. When the script executes document.write() calls fill the “hidden” DIV with the intended content.
<div id="skypeUsDummy" style="display: none;">
<!--
Externally loaded JavaScript code
-->
<script type="text/javascript"
src="http://download.skype.com/share/skypebuttons/js/skypeCheck.js">
</script>
<a href="skype:GetSnappy.com?chat">
<img src="http://download.skype.com/share/skypebuttons/buttons/chat_green_white_164x52.png"
style="border: none;" width="164" height="52" alt="Chat with me" />
</a>
</div>
Next we’ll unveil the source for Ad Delay which should be included at the very bottom of your web page. Ad Delay is a tiny JavaScript module containing one function, adDelay.swapOut.
/*
* Name: Ad Delay v0.1
* License: GNUv2 (www.gnu.org/licenses/gpl-2.0.txt)
* Auther: Brian Gardner <getsnappy@ymail.com>
* Usage:
*
* adDelay.swapOut(arg1, arg2)
* arg1 - the id of the placeholder div (in our example, skypePlaceholder)
* arg2 - the id of the dummy div (in our example, skypeDummy)
*
*/
var adDelay = {
swapOut: function(placeholderId,dummyId) {
var dummy = document.getElementById(dummyId);
var placeholder = document.getElementById(placeholderId);
if (!dummy) {
alert("element with id " + dummyId + " does not exist");
}
if (!placeholder) {
alert("element with id " + placeholderId + " does not exist");
}
/* loop through dummy nodes removing any JS nodes, preventing double execution */
for (index = dummy.childNodes.length - 1; index >= 0; index--)
{
var element = dummy.childNodes[index];
if ((element.nodeName == 'SCRIPT') || (element.nodeName == 'NOSCRIPT'))
dummy.removeChild(element);
}
dummy.parentNode.removeChild(dummy);
placeholder.parentNode.replaceChild(dummy, placeholder);
dummy.style.display = 'block';
}
};
After we've included the source to Ad Delay, we call adDelay.swapOut to perform the swapOut. Your page now loads faster thanks to Ad Delay : = ).
<script type="text/javascript">
adDelay.swapOut('skypeUsPlaceholder','skypeUsDummy');
</script>
| Print article | This entry was posted by brian on October 16, 2009 at 11:47 am, and is filed under Website Optimization. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
about 2 years ago
Hi
Thank you for the code.
How would would go about using the above code to insert more than one ad from say different networks.?
cheers
about 2 years ago
Simon
Process the ads individually. What I mean is place a swapout call after each script, and don’t call two script tags without calling swapout to the first. If you don’t both scripts are fully loaded before either ad is displayed.
about 2 years ago
thanks brian,
I didn’t see your comment at the foot of the article until today when I noticed the link to the comments at the beginning of the article. So this is a snippet of what I did
Ad1
Javascript Code
Ad2
Javascript Code
Ad3
Javascript Code
And then at the bottom I had
adDelay.swapOut(‘Ad1holder’,'Ad1′);adDelay.swapOut(‘Ad2holder’,'Ad2′);adDelay.swapOut(‘Ad3holder’,'Ad3′);
As for the ad delay code rather than placing this in the footer I put this in a asynchronous js code called within the head of the document.
about 1 year ago
Hi Brian
I get odd behaviour when I click on the firefox browsers forward and backwards button the ads seem to swap places. Any ideas what may be causing it?
thanks
about 1 year ago
Hi Brian,
This is a great article!
Just curious why something as simple as the following can’t be used (apologize if it did not paste well). I tried this on a test page http://www.keepbusy.net/about.php and it seems to perform with no issues.
function toggleAd(div1, div2)
{
document.getElementById(div1).innerHTML = document.getElementById(div2).innerHTML;
document.getElementById(div2).innerHTML = ”;
}
toggleAd(‘leaderboard’,'leaderboard2′);
toggleAd(‘mediumRectangleAd’,'mediumRectangleAd2′);
toggleAd(‘skyscraperAd’,'skyscraperAd2′);
Also, some Ad Networks auto-check Ad Placement (I’m assuming with javascript as the Ad loads), and I’m assuming these will be recorded as “below the fold” so I’m hesitant to implement side-wide. Any suggestions?
Thanks!!
about 1 year ago
The main difference in my function is the removing the script tags from the original so that they don’t get processed a second time. Not all browsers need that and I forget which one did (Opera, Firefox, or Safari maybe). My solution was tested on IE6,IE7,IE8, Firefox 3.0, Opera, and Safari
I wonder how they would auto-check add placement. I would implement such a feature by parsing the web page, locating the ad code, then assigning a score based on the html before and after the ad code. It seems that the ad agencies are more likely to score deliver ads based solely on click though rate, and I wonder if it isn’t just a marketing ploy to get webmasters to place their ads higher on their pages.
about 1 year ago
Hi Brian
Sorry for the late reply, some idiot decided I would look good on their car bonnet. You can find the link here http://www.flasharcadegamessite.com
What I’ve done is stuck all my javascript into one file (j15.js) with the ad delay code at the top, ad delay works but one occasion when you traverse the back and forward pages the divs seem to swap around and the ads swaps places with each other.
thanks