Non–blocking Facebook and Twitter buttons

On all the posts on this blog (like on most other websites you probably visit) you’ll see buttons to ‘Like’ a post (from Facebook) and to ‘Tweet’ about a post (from Twitter or TweetMeme). These buttons are very popular but if you use the iframe versions of the buttons (which are easy to install) you may have noticed a problem.

twitter facebook tweetmeme logos

If either the Facebook, Twitter, or TweetMeme servers don’t respond quickly enough when your browser requests the page content, your page loading may well block. On this site I’ve seen the Facebook Like button delay the page by 1-3 seconds. The bad part about the type of blocking is that in most browsers the rest of the page doesn’t render whilst the browser is waiting for these 3rd party servers to respond. There’s a more in depth explanation of why this is so on Steve Souders’ High Performance Web Sites blog.

Browsers usually start loading resources in the order that they are specified in the HTML. Below is a screenshot of one of the pages on this site (this one in fact). The red line shows the order of loading of the page. This order is typical for blogs.

rml page load order facebook twitter

If you place the social bookmarking buttons before your content then the problem is particularly noticeable as they can block your whole content from loading. During which time your visitor may decide to go elsewhere.

Is there a solution? Yes there is a well understood solution to this problem. Simply load these externally hosted buttons after your content. Here’s how I did it on this site.

Use a div to reserve space for your buttons

You should reserve the correct amount of space for your buttons. If you don’t you’ll cause the page to be re-rendered once the buttons are inserted.

<div class="socialbuttons" style="width:450px; height:28px; text-align: top;">
</div>

In my case I’m including the compact Facebook like button which is 25 pixels high, and either the TweetMeme button (20 pixels), or the Twitter Tweet button which is also 20 pixels high. More about how I decide on which Twitter button to include later.

For this blog I’m including the buttons at the start of my content, and at the end. If you are using WordPress you could add the div to your content either directly in the template (single.php) or by using a plugin such as PostPost.

I’m including the top div in the template, and the bottom div using PostPost. The reason I’m using PostPost for the bottom div is because this plugin gives itself a priority of ‘1’ which means that it inserts the div before most of my other plugins insert their content.

User JavaScript to add the Facebook/Twitter buttons after the content has loaded

You’ll notice that the div has the id ‘socialbuttons’. This allows us to easily find the element and insert the social bookmarking buttons after the content has loaded.

Here is the WordPress specific JavaScript that I’m using. I add it just before the closing </body> tag. For WordPress this means editing the footer.php template.

<script  type='text/javascript' language='javascript'>
<!--
var permalink='<?php echo urlencode(get_permalink()); ?>';
var socialhtml='<iframe src="http://www.facebook.com/plugins/like.php?href=' + permalink + '&amp;layout=standard&amp;show_faces=false&amp;width=300&amp;height=25&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:300px; height:25px; display:inline;"></iframe>';
<?php if (new_twitter()) { ?>
socialhtml += '<iframe allowtransparency="true" frameborder="0" scrolling="no" src="http://platform.twitter.com/widgets/tweet_button.html?url=' + permalink + '&via=reviewmylifeuk&related=reviewmylifeuk&text=<?php echo the_title(); ?>" style="width: 130px; height: 20px;"></iframe>';
<?php } else { ?>
socialhtml += '<iframe src="http://api.tweetmeme.com/button.js?url=' + permalink + '&style=compact&source=reviewmylifeuk&b=2" height="20" width="90" frameborder="0" scrolling="no" style="border:none; overflow:hidden; display:inline;"></iframe>';
<?php } ?>
var divs=document.getElementsByTagName('div');
var divcount=divs.length;
for (var i=0; i<divcount; ++i) {
	if (divs[i].className=='socialbuttons'){
		divs[i].innerHTML=socialhtml;
	}
}
//-->
</script>

This JavaScript works by find all the div tags with the class ‘socialbuttons’ and then inserting the Facebook and Twitter HTML inside the div tags.

I’ve highlighted in red my Twitter account name. You’ll want to change these values to your own Twitter account name. If you aren’t using WordPress you’ll need to replace the get_permalink() function with something that correctly encodes your current page URL.

You may be wondering what the new_twitter() function is.

PHP to select TweetMeme or Twitter Tweet button

TweetMeme is handing over the Tweet button to Twitter. As of July 2010 the recommended button to use (recommended by both TweetMeme and Twitter) is the official Twitter one. Unfortunately the Twitter Tweet counts will only be correct for articles posted after July 2010. Therefore for the moment I’m using the TweetMeme button for articles posted before July, and the Twitter one for articles posted after.

Here is the WordPress specific PHP that checks if the current post is after July 2010 (you could make it a one-liner if you like).

function new_twitter(){
	$twitter_switchover_date = strtotime("2010-07-01");
	$post_date= get_the_time('U');
	if ($post_date > $twitter_switchover_date) { 
		return true;
	} else {
		return false;
	}
}

If they ever remove the TweetMeme button completely it will be very easy with this code to change all the Twitter buttons to be the official Twitter ones.

Including hashtags with the TweetMeme button

The old TweetMeme button had the option of specifying hashtags for the Tweet. You can add this in as well if you want. You’ll need to write a function to get the hastags (e.g. called something like get_hashtags()), and include it in the TweetMeme URL.

You can find code for constructing the TweetMeme hashtags in the TweetMeme plugin. Look in tweetmeme.php for the ‘// append the hashtags’ section.

If you manage to create your get_hashtags() function you can replace the TweetMeme line in the JavaScript with.

socialhtml += '<iframe src="http://api.tweetmeme.com/button.js?url=' + permalink + '&style=compact&source=reviewmylifeuk<?php echo get_hashtags() ?>&b=2" height="20" width="90" frameborder="0" scrolling="no" style="border:none; overflow:hidden; display:inline;"></iframe>';

(again don’t forget to replace my Twitter account name with yours!)

Does it make a difference?

From my experience of using this code it definitely makes a difference. The annoying delays (caused mainly by the Facebook Like button) have gone. The button still sometime takes several seconds to load, but at least it isn’t blocking the rest of the page.

More info on how to customise the buttons

If you want to customise the buttons have a look at the developer documentation for each one.

Leave a Reply

Your email address will not be published. Required fields are marked *

Do NOT fill this !