Remote JavaScript includes without the performance penalty (part 1)

Lots of social services like Flickr and del.icio.us provide JavaScript snippets that you can include in your web page to display your latest photos or bookmarks or what-have-you.

Unfortunately, if you want to place the snippet near the top of your page, this means that the rendering of the entire page gets held up until the snippet finishes loading, which can be a big inconvenience if the remote server tends to be slow to respond (I'm looking at you, Flickr).

I recently got fed up with this and decided to do something about it. Here's how you can keep your Flickr badge (or any other JavaScript include) from slowing down page rendering with just a few lines of code.

For the sake of this example, let's say we have a very basic web page like this one:

<html>
  <head>
    <title>Bob's Ninja Page</title>
  </head>
  <body>  
    <div id="page">
      <div id="sidebar">
        <dl>
          <dt>Flickr Photos</dt>
          <dd id="flickr">
            <script src="http://www.flickr.com/[...]"></script>
          </dd>
        </dl>
      </div>
    
      <div id="content">
        <p>
          Ninjas are awesome.
        </p>
      </div>
    </div>
  </body>
</html>

Since the Flickr badge is being included early in the page, it'll slow things down and annoy our readers, who are very eager to learn about ninjas. To prevent this, we'll add a new hidden div at the very bottom of the page, just before the </body> tag, and we'll put the Flickr JS include inside that div so that it won't load until after the rest of the page:

<div id="fakeflickr" style="display: none;">
  <script src="http://www.flickr.com/[...]"></script>
</div>

Now we've solved the performance problem, but there's no way for visitors to see our Flickr badge since it's hidden. We'll fix that with a bit of JavaScript, which we'll add just after our hidden div:

<script type="text/javascript">
  var flickr     = document.getElementById('flickr'),
      fakeflickr = document.getElementById('fakeflickr');

  flickr.innerHTML = fakeflickr.innerHTML;
  fakeflickr.innerHTML = '';
</script>

This works because the browser won't execute that snippet until after it executes the Flickr include, so by the time our code runs, we know that the hidden div contains the badge HTML. All we need to do is move that HTML into the real badge container, and voila, problem solved.

Of course, this will result in the Flickr badge suddenly appearing in the sidebar out of nowhere, which might be a little distracting if the visitor has already started reading about ninjas. As you may have noticed, I've tried to minimize that distraction on wonko.com by having the Flickr badge fade in gradually.

Tune in tomorrow for part 2 to learn how to add this animation to your own pages. It's easier than you might think.