
I was unhappy with the user experience that my asynchronous loading changes introduced. It could take up to thirty seconds, and two pauses with blank browser windows due to reloads, before the user would see a set of photos.
So, I took a step back and tried to analyze the problem I was attempting to solve. I made these changes primarily because Facebook will show an error page if the server takes too long to produce a page. My first solution attempted to solve that by showing multiple intermediate loading pages, with artificial pauses between them to give the server time to do the time-consuming image processing.
The approach I’ve taken now is different. There’s a single page that’s loaded, but that then fires off an Ajax-style request to my server, asking for all the photos. The key thing is that this request will not produce a time-out error the way loading the same page directly through a Facebook frame will. It also avoids the blank page/reloading problem, instead you just see a loading message until the pictures are ready, and then that area is populated with photos. Another advantage is that there’s no artificial pause, instead the server returns the photos as soon as they are ready.
This doesn’t tackle the bigger problem of making sure that multiple image processing requests are handled efficiently, but the median response time still seems fast. The big problem before was that the less-common multi-second response times would be catastrophic, with an error page appearing instead of the expected result. Seeing the loading message for a few seconds instead is a lot less painful.
Here’s the actual code I use:
$ajaxurl = get_serverurl() . 'index.php?action=geteffectpicker' .
'&user=' . $user .
'&pickactionurl=' . urlencode($pickactionurl) .
'&ismessage=' . $ismessage .
'&sender=' . $sender .
'&sourceurl=' . urlencode($sourceurl) .
'&firstname=' . $firstname .
'&senderfirst=' . $senderfirst;
?>
<div id="delayedpicker" style="padding: 10px;">
<a href="http://apps.facebook.com/funhousephoto/">Funhouse Photo</a> is loading the portrait for <?=$\
firstname?>, you should see their pictures in a few seconds
<script><!--
var ajax = new Ajax();
ajax.responseType = Ajax.FBML;
ajax.ondone = function(data)
{
document.getElementById('delayedpicker').setInnerFBML(data);
}
ajax.requireLogin = true;
ajax.post('<?=$ajaxurl?>');
//--></script>
This is all using Facebook’s MockAjax functionality, since real XMLHttpRequest calls are not allowed for security reasons. It took me a while to get working, mostly because I was calling $facebook->require_login() at the start of the PHP code that created the picture content. I discovered that this would try to redirect to the Facebook login page, and since the request is headless and you can’t actually log in, an empty result would be returned.
Instead, I ended up encoding all the information I needed from the Facebook API into the request URL, such as the first names of the users, and the URLs to use to pick a picture. This meant I was able to create the pictures without logging in to Facebook, and then it all worked swimmingly.
Funhouse Photo User Count: 701 total, 66 active. Still growing slowly, and I haven’t had time to add any more effects, or implement feed functionality.