P3PC: Facebook Share

March 1, 2010 8:35 pm | 1 Comment

P3PC is a project to review the performance of 3rd party content such as ads, widgets, and analytics. You can see all the reviews and stats on the P3PC home page. This blog post looks at Facebook Share. Here are the summary stats:

impact on page Page Speed YSlow doc.
total reqs total xfer size JS ungzip DOM elems median Δ load time
small 90 92 n 5 8 kB 7 kB 15 104 ms
column definitions
Click here to see how your browser performs compared to the median load time shown above.

Facebook Share is a way to share a URL with the Facebook community. Here’s what it looks like. (This is a static image. Go to the Compare page to see the live widget.)

Snippet Code

Let’s look at the actual snippet code:

1: <a name=”fb_share” type=”button_count” share_url=”http://stevesouders.com/” href=”http://www.facebook.com/sharer.php”>Share</a>
2: <script src=”http://static.ak.fbcdn.net/connect.php/js/FB.Share” type=”text/javascript”></script>
snippet code as of March 1, 2010

A quick walk through the snippet code:

  • line 1 – The anchor that will be filled in later.
  • line 2 – The FB.Share script is downloaded. The actual code is minified, but I’ve expanded some of it here for easier readability. The _onFirst function is called (line 1 below). _onFirst inserts the share-button-css stylesheet (lines 2-6) and then calls renderPass. renderPass calls fetchData which inserts the restserver.php script (lines 12-14). The insert function appends the DOM element (stylesheet or script) to the head or body of the document (line 19).
    1: _onFirst: function() {
    2: var a=document.createElement(‘link’);
    3: a.rel=’stylesheet’;
    4: a.type=’text/css’;
    5: a.href=’http://static.ak.fbcdn.net/connect.php/css/share-button-css’;
    6: this.insert(a);
    7: renderPass();
    8: […]
    9: },
    11: fetchData: function() {
    12: var a=document.createElement(‘script’);
    13: a.src=this.addQS(‘http://api.ak.facebook.com/restserver.php’, {v:’1.0′,method:[…]});
    14: this.insert(a);
    15: […]
    16: },
    18: insert: function(a) {
    19: (document.getElementsByTagName(‘HEAD’)[0]||document.body).appendChild(a);
    20: },

Performance Analysis

This HTTP waterfall chart was generated by WebPagetest.org using IE 7 with a 1.5Mbps connection from Dulles, VA. Item 5 (facebook-sharer-waterfall.png) is the first resource that’s part of the main page. Notice how it’s blocked by the first Facebook Share script, but then loads in parallel with the widget’s stylesheet and second script.

Here are the most important performance issues along with recommended solutions.

1. The FB.Share script blocks resources and rendering.

It’s great that the stylesheet (share-button-css) and second script (restserver.php) are loading dynamically and don’t block the main page’s resources (facebook-sharer-waterfall.png). But the first script (FB.Share) is loaded with the typical SCRIPT SRC tags and so does block in older browsers, and even in newer browsers will have some blocking effects. Because there are no code dependencies and no use of document.write (yay!), the FB.Share script can also be loaded asynchronously. Here’s what the async snippet might look like. (Warning: I haven’t tested this on all browsers.)

1: <a name=”fb_share” type=”button_count” share_url=”http://stevesouders.com/” href=”http://www.facebook.com/sharer.php”>Share</a>
2: <script type=”text/javascript”>
3: (function() {
4: var domscript = document.createElement(“script”);
5: domscript.type = “text/javascript”;
6: domscript.src = “http://static.ak.fbcdn.net/connect.php/js/FB.Share”;
7: (document.getElementsByTagName(“head”)[0] || document.getElementsByTagName(“body”)[0]).appendChild(domscript);
8: }());
9: </script>

This async snippet is used in the Facebook Sharer Improved example. The HTTP waterfall chart for this async snippet is shown below. The most important thing about loading the FB.Share script asynchronously is that the main page’s content can load more quickly. Notice how the image in the main page (facebook-sharer-waterfall.png) moves from item 5 to item 3, and its load time moves from ~1100 ms to ~780 ms. Another benefit is that the overall page load time is faster, dropping from ~1100 ms to ~900 ms.

2. share-button-css is only cached for a few minutes

share-button-css should be given a far future expiration date. If it’s changed, the filename could be modified in FB.Share guaranteeing that everyone got the updated file.

3. The CSS could be reduced.

Page Speed reports that 50% (2.9 kB) of the CSS isn’t used. It’s possible the CSS is used in other manifestations of the widget but not in this default view.

What you can do now: Facebook Share is a lightweight widget as widgets go. In addition to a small transfer size and small amount of JavaScript, its images and CSS selectors are also optimized. But if you wanted to reduce the impact even farther, you could try loading FB.Share asynchronously.

One Response to P3PC: Facebook Share

  1. That’s a better idea. Using ajax to call FB.Share.
    So much things going on with a little button… Nice post :)