Latency optimizations: Feel the need... the need for speed!

Wednesday, May 14, 2008 at 11:06 AM



In the social application space, speed is king. Is your application providing a poor user experience by taking too long to load? The Firebug extension for Firefox has support for measuring the latency of your orkut applications. You can obtain the measurements for your application by loading your application and checking Firebug's "Net" tab to see how long your application takes to load completely.

If you're seeing loading times of:
  • Less than 5 seconds on the canvas and less than 2 seconds on the profile - your application is doing great!
  • Between 5 and 10 seconds on the canvas and between 2 and 5 seconds on the profile - your application should be tweaked to reduce latency.
  • Over 10 seconds on the canvas and over 5 seconds on the profile - you MUST improve the performance of your application.
If your app falls in the latter two categories, we've got some techniques you need to use to ensure a better user experience. Since our last post about reducing application latency, the orkut team has been hard at work identifying areas where application load times can be significantly reduced and has made some improvements to the sandbox. Some of these changes will improve your application latency automatically, and others will require a bit of extra work to take advantage of. All of these techniques will help your applications load faster, reduce the load on your servers, and help increase the stability and reliability of the application platform as a whole.

For a complete list of approaches you can use on orkut to decrease application latency, make sure that you check out the Latency Combat Field Manual, which has been updated to include the approaches listed here. These changes are currently live on the sandbox and will be rolling out to production soon, so be sure to start using the following as soon as possible:

Preload for makeRequest calls
Many applications wait for a registerOnLoadHandler callback before executing a makeRequest call, which slows down render time considerably. To combat this, orkut now allows for an extra parameter in your ModulePrefs which will instruct orkut to make a signed request while the application IFRAME is loading. If your makeRequest call looks like:

var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
gadgets.io.makeRequest("http://www.example.com", response, params);

You can preload the request by adding a <Preload> tag:

<ModulePrefs title="Demo Preloads" description="Demo Preloads">
<Require feature="opensocial-0.7" />
<Require feature="views" />
<Preload href="http://www.example.com" authz="signed" />
</ModulePrefs>

When your application IFRAME loads, the response from example.com will be available inline in the HTML surrounding your application. When your application executes the makeRequest
call, this content will be returned instantly, without needing to hit your server again. Notice that this approach supports signed requests through the use of the authz parameter, so your data can load fast AND be verifiable.

There are additional things you can do with the element-- make sure that you read the updated Latency Combat Field Manual section on preloads for additional information.

What are the benefits?
Users no longer need to wait for your application to finish loading on orkut before executing a makeRequest call. Orkut will make the request and insert the response directly into the application as it renders your application.

Improved respect for cache headers
Orkut now offers better support for the Cache-Control HTTP header. You have server-side control over how your resources are cached, so be sure to set your headers appropriately for maximum benefit.

The Cache-Control header is best described in the HTTP/1.1 specification but there are some simpler descriptions available as well. If you're not sure about the cache headers your server is currently sending, you can try some publicly available tools to examine the cache headers on your files and see if they need to be tweaked.

Be aware that the Cache-Control header will be examined for all content coming from your server, including XML application specs, responses from makeRequest (both prefetched and not) and proxied images. Be sure to set caching headers for everything!

A note for Apache users: Apache defaults to using Last-Modified and ETag headers to control caching for static files, rather than the recommended Expires and Cache-Control: max-age headers. If you are using Apache, change your cache headers to Expires and max-age.

What are the benefits?
Your server has much more control over how orkut caches its content. You can set a low cache expiration for content that changes often, and a high cache timeout for content that does not change. Caching will become much more efficient once you set the appropriate headers.

Reducing the number of fetches
Some internet browsers (like IE7) will only download two files from a given server at a time, shared amongst all HTML, XML, image, CSS, and JavaScript files. To reduce the number of connections that a user has to make back to your server, consolidate and inline as much code as possible.

If your JavaScript includes look like:

<script src="http://www.example.com/javascript.core.js" type="text/javascript"></script>
<script src="http://www.example.com/javascript.extra.js" type="text/javascript"></script>

You should combine each file into one master JavaScript file:

<script src="http://www.example.com/javascript.all.js" type="text/javascript"></script>

Better yet, inline your code if at all possible:

<script type="text/javascript">
function1() {
...
};
...
</script>

This will save server connections for other assets. Remember that this approach can be used for CSS, as well.

To decrease the number of image files your application needs to load, you can use image spriting to combine all your image files into a single master "sprite" file. Check out A List Apart's CSS Spriting article for a good description of this technique.

Generally speaking, concatenating your files is a great performance improvement you can make. Because of the aggressive caching that orkut performs, even using a relatively slow server-side script to automatically concatenate files will still wind up performing better than separate files (once the automatically concatenated file is cached). Aim for a single CSS and a single JS file in production.

What are the benefits?
This approach keeps the number of server connections low, and reduces the total number of HTTP requests that each user of your application has to make.

Automatic remote file caching
You probably already know how to get proxy URLs for dynamically inserted page elements using the getProxyUrl function. However, this technique does not help cache image, script, or style tags that are directly embedded in the source of your application. Orkut will now rewrite the href attributes on these elements as proxied URLs, meaning that all non-dynamic references to remote content will automatically get the benefit of caching.

If your source contains an image tag which looks like

<img src="http://www.example.com/i_heart_apis.png" />

orkut will render the image tag as

<img src="http://www.gmodules.com/ig/proxy?url=http%3A%2F%2Fwww.example.com%2Fi_heart_apis.png" />

Note that any HTML fetched using makeRequest or otherwise passed through the proxy will also have its links rewritten in this manner. Caching is now automatic throughout your entire application.

What are the benefits?
This approach can dramatically reduce the load on your server for image, CSS, and JavaScript resources that are directly included in your application source, without you needing to change any code at all.

Additional Ideas
You should now have a wealth of techniques to use to speed up your application on orkut. For an updated list of optimizations your applications may use, check out the updated Latency Combat Field Manual. If you want additional suggestions, please check out the YSlow tool for Firebug, which can analyze your application and give suggestions on areas for improvement.

Remember, every little bit counts when you're tuning an application for millions of potential users! Use as many of these techniques as possible to decrease load times and keep your users (and servers) happy. Be sure to join us in the groups or in the #opensocial channel on Freenode IRC if you have further questions.