February 26, 2013Web · Platform · Performance · JavaScript · User Experience

Like Box plugin: Now 2-4x faster

Stoyan Stefanov

Following in the footsteps of the new, faster Like button plugin, we've been busy rewriting the Like Box from the ground up, focusing on performance.

We're happy to report that the new Like Box plugin is significantly faster than the old implementation. So what changed?

  • New, smaller components. The plugin is made of little components (box, buttons, etc), and we've simplified and cleaned those up to use fewer bytes in HTML markup and CSS.
  • The total CSS is reduced to the point of being small enough to go in the HTML as a style tag. This may seem controversial (external stylesheets can be cached, inline styles cannot), but in our experiments we've seen it's better to have the (small amount of) CSS inline. Otherwise the browsers block the rendering of the page, waiting for yet another HTTP request to complete.
  • Reduced overall JavaScript size.
  • Better JavaScript packaging. We now have only one JavaScript to load with a single HTTP request.
  • Asynchronous non-blocking JavaScript loading.
  • Perceived performance. Inline CSS and non-blocking JavaScript make the first browser paint happen faster. This helps deliver the first impression to the user faster. The rest (handling clicks and showing the page stream) can wait.

You can take a look at some WebPagetest runs. It's easy to compare the before and after because we've kept the old deprecated version of the Like Box (known as Fanbox) in the codebase.

(Note: If you're still using the deprecated fb:fan or loading plugins/fan.php, now is a good time to switch to fb:likebox or plugins/likebox.php if you're using the iframe version.)

1. Take a look at the simplest form of the Like Box: no stream, no friend faces, almost like a Like Button (example):

As you can see, there are much fewer resources now: 4 down from 15. The whole plugin loads in 0.5 seconds, as opposed to 2.3 seconds (a 4x improvement). Additionally, the perceived performance is better because the first paint (initial impression) is now at 0.3 seconds, as opposed to 2.1s (a 7x improvement!). Finally, the total payload in terms of bytes is 46K, or 5x fewer bytes than before (when it was 245K).

2. Next, take a look at the waterfalls when the show_faces option is true (example):

We have more requests because of the friend's photos, but the initial paint is 0.3s (was 2.1s) and the onload fires at 0.75s (was 2.4s).

3. The most complex configuration is when you have a stream of posts as well as friend photos (example):

This configuration works as follows: everything's the same as #2, except when the asynchronous JavaScript arrives, it makes an XMLHttpRequest to get the content of the stream. Once the stream arrives, we display it and request additional photos required by the stream.

The numbers (first paint, DOMContentLoaded, onload) are unchanged from case #2, since the XHR request is "lazy". The difference is that now the stream content doesn't require additional JavaScript files like it used to. Also, any additional CSS required by the stream is inline so the stream is not blocked by additional requests and can render at 1.9s (as opposed to 3.3s in the "before" case).

The very last component arrives at 2.7s now (was 3.9s), but that's not all that interesting since most of the images are "below the fold" of the scrollable stream.

Thanks very much for reading! Hope your visitors will also appreciate the faster social plugins.

(And if you haven't yet, don't forget to migrate from the deprecated and slower Fanbox to the new Like Box plugin.)

Keep Updated

Stay up-to-date via RSS with the latest open source project releases from Facebook, news from our Engineering teams, and upcoming events.

Facebook © 2017