【转】facebook bigpipe技术实践

原文:http://ajaxian.com/archives/facebook-javascript-jsconf

Makinde Adeagbo is describing Facebook's Javascript performance optimisation efforts at JSConf. By 2009, it became clear something had to be done, as the trend was towards longer and longer page loads. Back in 2006, the objective had been super fast page loading: "If any page loads in under 100ms, it takes way too long". By 2008, given all the new interactive features on the page, the 100 millisecond target had expanded to 1 second, and by mid-2009, pages were taking 5 seconds to load. Even HipHop, the PHP compiler, was smaller than the Javascript code base. And when Steve Souders called out Facebook in his book numerous times, it only adding to the team's sense of fun and joy ;).

In June 2009, the team quickly chose a target by year's end by simply checking the load time without Javascript: 2.5 seconds. Thus, dropping load time from 5 seconds to 2.5 seconds was the goal for end of 2009.

The first initiative was to include the Javascript at the bottom of the page. Great, it's faster, but at what cost? A big one: Users try to click on controls, and nothing happens. Back to the drawing board, and the team refined the setup so that the actionable stuff was initialised on the top of the page. But how to minimise all this code at the top of the page? Here, the team exploited the observation that most controls work the same way:

* User clicks
* Sends ASync request
* Insert/Replace some content

So the team set up elements like this:

<a href="/ring.php rel="dialog">...</a>

... And then hijacked them with a standard listener routine, one that would work for most of the controls. (Most, not all; 80/20 principle is in effect here.) This way, they could have one small listener routine to handle most of the controls on the page. Once the user clicks, the server gets called and outputs a new snippet of Javascript:

The Javascript:

JAVASCRIPT:
new Dialog().setTitle().setBody().show();

would be output by a PHP script, and then evaluated in the browser:

PHP:
$response = new DialogResponse();
$response->setTitle()->setBody()->send();

(A form of On-Demand Javascript.)

In fact, the team has a whole PHP library for outputting Javascript. For example, when a request comes in to expand a new story:

PHP:
$response = new AsyncResponse();
$response->setContent("#elem_id"$new_content);
$response->appendContent("#content .stories"$new_story);
$response->send();

And they are using a convention: "ajaxify=1" on an element indicates it's ... Ajaxified.

At this point, the team had now Ajaxified a bunch of features, but people were still skeptical about more complicated features. For example, would setting status be too hard with the same techniques. So after some research, Makinde came back with an epiphany: the humble form. Whereas the previous async requests were effectively information-less - just a simple directive and maybe an ID - the requests would now include content too. And of course, most of these things look nothing like forms due to styling. But underneath, they're still forms, e.g. the entire comments block is a single form.

Nowadays, most of Facebook runs without complete page refreshes, by dynamically flipping the content and the fragment ID. (What Facebook calls page transitions.)

Ongoing, Makinde says performance optimisation requires ongoing vigilance. Every engineer has their special case, but in the scheme of things, it's better to say no to new features unless they can be strongly justified. For example, we can live with user submitting a form that hasn't yet been hijacked; a complete page refresh is fine on occasion. We don't like it, but we don't want to make it a special case just for the sake of it.

The Gantt charts tell a great tale: users now see content much earlier, and it's interactive. So how did they fare with that 2.5 second goal for year's end? Achieved by December 23. And Makinde wants people to know Facebook is hiring as they have more Javascript to write...and delete.

UPDATE: And here are the slides ...

posted @ 2010-11-17 22:29  wingle  阅读(355)  评论(0编辑  收藏  举报