I have a site with posts, and I am implementing Facebook comments on them. All the posts will be in one page, and below each a 'Comments(3)' link. Once this is clicked it will go to the comments page of this post, showing the Facebook plugin.
My problem is that obtaining that 3 from 'comments(3)' is taking a while... How can I optimize this? This is how the page where the comments are looks like: https://graph.facebook.com/?ids=http://example.com/
On the page where I get the comments, this is what I have for each post:
echo $postsClass->getCommentsCount($post['id'])
And then this is how the getCommentsCount function looks like:
public function getCommentsCount($postId) {
$commentsCount = 0;
$url = 'http://myurl.com?post=' . $postId;
$html = file_get_contents('http://graph.facebook.com/?ids=' . $url);
$comments = json_decode($html, true);
if (array_key_exists('comments', $comments[$url])) {
$commentsCount = $comments[$url]['comments'];
}
return $commentsCount;
}
It seems to take around 3 or 4 seconds to load the comments for 6 posts... Any ideas on how to improve this?
Thank you!
The Facebook Graph API supports Real-time Updates via a subscription system.
I'm not sure if there is a delay in the change notice delivery; it is guaranteed to be more efficient, however. As you receive the updates, simply cache the results in your your database for quick retrieval. Be warned that it can be quite a heavy load if you are subscribing to many quickly changing objects.
Another alternative is to schedule your server to poll the comments every so often (every few minutes?) and store the information.
Or, you could present the page and then have the user's browser query the comment count via AJAX. The user could retrieve the information via your server, or directly from Facebook if they has access to the object in context.
I'm in a big rush today so can't really give you more detailed answer but you should try doing a batched request http://developers.facebook.com/docs/reference/api/batch/
The standard version of the Graph API is designed to make it really easy to get data for an individual object and to browse connections between objects. It also includes a limited ability to retrieve data for a few objects at the same time.
If your application needs the ability to access significant amounts of data in a single go - or you need to make changes to several objects at once, it is often more efficient batch your queries rather than make multiple individual HTTP requests.
To enable this, the Graph API support Batching. Batching allows you to pass instructions for several operations in a single HTTP request. You can also specify dependencies between related operations (described in a section below). Facebook will process each of your independent operations in parallel and will process your dependent operations sequentially. Once all operations have been completed, a consolidated response will be passed back to you and the HTTP connection will be closed.
To expand on @Jont's answer, let me give you an example of how to do batch requests.
Let's say we have a list of user ids and we want to get the names for these users.
$userIds = array('1234', '3456', '5678', '7890');
$queries = array();
foreach ($userIds as $userId) {
$queries[] = array('method' => 'GET', 'relative_url' => '/'.$userId);
}
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');
foreach ($batchResponse as $response) {
$user = json_decode($response['body'], true);
$users[$user['id']] = $user;
}
This will fetch all users with just a single http request.
In general, it is a good idea to pre-fetch that data and store it locally, as you don't want to make requests to the graph API on every request.
What about FQL? It's limited to I think 5000 objects, but that should be more than enough, and it allows you to pinpoint exactly what you want to retrieve, which would probably be faster.
You could use the Facebook comments count plugin:
Comments(<fb:comments-count href=http://example.com/></fb:comments-count>)