Phillip Pearson - web + electronics notes

tech notes and web hackery from a new zealander who was vaguely useful on the web back in 2002 (see: python community server, the blogging ecosystem, the new zealand coffee review, the internet topic exchange).

2006-6-9

Javascript "badges" that don't kill your page load process

One thing you can do in PeopleAggregator is show your friend list (well, part of it) on your blog, using a Javascript include of the type pioneered by blogrolling.com and commonly used for advertising (e.g. AdSense) and all sorts of blogging things. You include some markup on your site that looks like this:

<script language="javascript" type="text/javascript" src="http://www.peopleaggregator.org/web/badge.php/js/26/friends/6/"></script>

And you get a nice display of your current friends, like this:

The only problem is that <script> tags which load extra scripts like this cause your browser to pause rendering the page while the script loads. Apparently there's no way for browser makers to fix this, as scripts can do anything to the page that they like, and browsers aren't allowed to run them out of order. Or something.

Also, if the site generating the Javascript goes down, you may get a browser error. If it doesn't go down, but just gets really slow, your blog page may never display. The Radio Userland comment server went through a bad patch a while ago where its slow Javascript delivery was bogging down the display of all blogs that used radiocomments.userland.com.

BUT, there's something USERS can do to get around this. I'll make it a bit easier to do this in the final version of PeepAgg, but for the moment here's a solution that you can retrofit it to any 'badge' display that uses document.write to write its own HTML into your page.

Basically, you move the script include down into (or after) your footer, so that it runs AFTER the whole page has rendered. Then you temporarily replace the document.write function with something that collects the data, then after the script finishes running, you drop that data in a div (prepared earlier).

Here's how it looks. First we have the div, which you put in your sidebar:

<div id="peepagg_badge_goes_here"><p>Loading ...</p></div>

Now right at the end of your main blog template, you do this:

<script language="javascript"><!--
var old_document_write = document.write;
var peepagg_badge_data = "";
document.write = function(s) {
peepagg_badge_data += s;
}
// --></script>
<script language="javascript" type="text/javascript" src="http://www.peopleaggregator.org/web/badge.php/js/26/friends/15/"></script>
<script language="javascript"><!--
document.write = old_document_write;
document.getElementById("peepagg_badge_goes_here").innerHTML = peepagg_badge_data;
// --></script>

The line in bold is the original script include. Everything else is the code to gather up the badge HTML as the included script calls document.write, then drop the data into the div.

BTW, I've implemented this for this blog, so if you refresh this page you should see that the "facewall" on the top of the sidebar appears after the rest of the page finishes loading, rather than holding up the whole page like the facewall included in this blog post. Handy!