Taming the Gravatar

The service Gravatar seems to be a great service in theory: anyone who registers a picture with an email address there can have this picture associated with oneself in all applications that support Gravatar. This defies the need to having to upload a profile picture for every application being used.

With so many things that work in theory, Gravatar has had and is having some serious issues. Their servers dont quite work as well as expected. This results in pages trying to render a Gravatar image stalling and becoming irresponsive.

Since an early stage, Opinion had Gravatar support. What worked quite well in the beginning became now a hassle with pages taking forever to load. However, it does not have to be like that.

The Solution

Instead of requesting the images while rendering the page, we now request the images after the whole page has loaded via javascript. Let’s have a look at how this can be done:

Before we were having a simple image tag that would get the correct url from a helper who would look like this:

http://www.gravatar.com/avatar.php?gravatar_id=#{Digest::MD5.hexdigest(email)}&size=40&default=http%3A%2F%2F#{@request.host + @request.port_string}/images/no-gravatar.jpg

(pretty straight forward and the way it was supposed to be implemented by Gravatar – it tries to get the right picture for the MD5 of the email address provided. If it can’t find a gravatar it points us back to the default picture we define)

Now, we decide to put that default picture as background image of the future gravatar image space.

We’re just rendering hidden tags for each gravatar with the MD5 Hash of the user’s email (so we can recreate the appropriate links later ourselves once the page’s rendering is done).

they can look like:


  <address class="gravatar" style="display:none"><%= Digest::MD5.hexdigest(comment.user.email) %></address>

Now we need to define a javascript method that would replace the content of an element with the correct Gravatar and one that will iterate through all potential Gravatar images:


var Gravatar = {
  replaceElement: function(element) {
    Element.replace(element, "<img src=\"http://www.gravatar.com/avatar.php?gravatar_id=" + element.innerHTML + "&size=40\" alt=\"\" />")
  },

  replaceAll: function() {
    $$('address.gravatar').each(function(e){
      Gravatar.replaceElement(e);
    });
  }  
}

Finally, we just need to register our replacing js goodness to be executed after load:


  Event.observe(window, 'load', function() { setTimeout(Gravatar.replaceAll, 50) } );

So ideally this will now result in the page being loaded, usable and Gravatars (for those that can be found) popping in with a short delay, covering the default user image.

Published: December 15th 08:48 PM under: