Transatlantic Facebook application performance woes

Posted on |

Someone I follow on Twitter reported having problems getting a Facebook application to perform. I don’t know what they are doing so this post is just guessing at their problem, but the fact is that — if you’re not paying attention — you can easily shoot yourself in the foot when building and deploying Facebook apps. The diagram below depicts a random fbml Facebook app deployed to a server located in Denmark being used by a user also situated in Denmark. Note that Facebook doesn’t yet have a datacenter in Europe (they have one on each coast in the US).

fbservers

The following exchange takes place:

  1. User requests some page related to the application from Facebook
  2. Facebook realizes that serving this request requires querying the application and sends a request for fbml to the app
  3. The app gets the request and decides that in order to respond, it has to query the Facebook API for further info
  4. The Facebook API responds to the query
  5. The application uses the query results and the original request to create a fbml response that is sent to Facebook
  6. Facebook gets the fbml, validates it and macroexpand various fbml tags
  7. Facebook sends the complete page to the user

… so that adds up 6 transatlantic requests pr. page requested by the user. Assuming a 250ms ping time from the Danish app-server to the Facebook datacenter this is a whopping 1.5s latency on top of whatever processing time your server needs AND the time taken by Facebook to process your API request and validate your fbml.

So what do you do? Usually steps 3 and 4 can be eliminated through careful use of fbml and taking advantage of the fact that Facebook includes the ids of all the requesting users friends. Going for an iframe app is also helpful because it eliminates one transatlantic roundtrip and spares Facebook from having to validate any fbml. A very effective measure if you insist on fbml, is simply getting a server stateside — preferably someplace with low ping times to Facebook datacenters. There are plenty of cheap hosting options around, Joyent will even do it for free (I’m not affiliated in any way).

Comments

Matthias on

You’re smarter than your appearance 🙂

Reply

Rune Sørensen on

I’ve also found it advantageous to avoid most API calls by using fbml. Not recommendable if you’re using FB connect though, as you’ll want to verify that the user in your session is actually the one who’s authenticated with facebook – and I haven’t yet found another way to verify this, than by doing an actual api call!?

Canvas and tab facebook apps can also benefit performancewise from making asynchronous calls whenever possible/feasible, because you can avoid the initial request to the facebook servers and in some cases you don’t have to wait for facebook to render and forward the response. Your server is contacted directly from the user’s computer through the FBJS ajax object, and facebook should only need to validate and render it if it contains fbml. If the ajax request doesn’t contain fbml, consider using AjaxLocalProxy (http://wiki.developers.facebook.com/index.php/FBJS_LocalProxy). If it does have fbml in it and needs to go through the fb server hop, the delay could also be considered more acceptable for the user experience, as it’s only a part of the page being updated, giving developers the possibility to entertain users by other means (than a full page load).

Generally my experience is that fb api calls takes about 0,7 – 2 seconds from a danish server. I haven’t taken the time to measure how long it is from my production server in the US though, but I would guess the 250ms (at best) ping time you’re talking about could definitely decrease performance of the page. So if it’s possible, I would agree that this is also a nice measure to ensure a performing fb app.

Reply

friism on

@RuneSørensen Excellent ressource(FBJS_LocalProxy), wasn’t aware of that.

Reply

Leave a Reply to Rune Sørensen Cancel reply

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