If you're a frequent visitor to code.google.com for product updates and reference materials for Google APIs you're working with, you might have noticed that the page loading time (or page rendering time depending on how you see it) has reduced in varying degrees in the past several weeks.
As you'll see below, we've made several changes to help reduce user-perceived latency. This is not an exhaustive list of all improvements we've made recently, but these are the major ones we've made.
As Steve Souders emphasizes as the "Performance Golden Rule" in his book High Performance Web Sites, "only 10-20% of the end user response time is spent downloading the HTML document. The other 80-90% is spent downloading all the components in the page (p.5)".
We agree. That's why we focused our effort on reducing the number and size of downloads (HTTP requests) for the "components" throughout Google Code.
- Combined and minimized JavaScript and CSS files used throughout the site
- Implemented CSS sprites for frequently-used images
Although browsers usually download several images in parallel, we concatenated these images into one image so only one HTTP request would be made. Of course, concatenating several images into one required us to make several changes in HTML/CSS. For example, instead of having:
We had to change it to:
- Implemented lazy loading of Google AJAX APIs loader module (google.load)
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
First, in the <head> section, we load the Google AJAX APIs loader module via DOM scripting only on the pages where it's required:
if (needToLoadGoogleAjaxApisLoaderModule) {
// Load Google AJAX APIs loader module (google.load)
var script = document.createElement('script');
script.src = 'http://www.google.com/jsapi?callback=googleLoadCallback';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
}
Then, in the Google loader callback handler (googleLoadCallback()), we initialize the AJAX Feed API and provide the function name that utilizes the AJAX Feed API (startUsingAjaxFeedAPI):
function googleLoadCallback() {
// Initialize AJAX Feed API
google.load('feeds', '1', {callback: startUsingAjaxFeedAPI});
}
function startUsingAjaxFeedAPI() {
// Start using AJAX Feed API
var feed = new google.feeds.Feed(someFeedUrl);
...
}In effect, we're loading the AJAX Feed API on-demand through the use of two consecutive callback handlers, first to load the Google AJAX APIs loader module (google.load) and then to initialize the AJAX Feed API before it's used. Similar technique can be used for the Maps API and the AJAX Search API.
By now you're probably wondering just how much of an impact did these changes have on Google Code anyways? According to our latency measurement stats, the user-perceived latency on Google Code dropped quite a bit, anywhere between 30% and 70% depending on the page. This is a huge return for relatively small investments we've made along the way, and we hope you'll find these techniques useful for your own web development as well.

9 comments:
This was quite helpful. Thanks a lot!
How about jQuery? You can do lazy loading of jQuery too.
Great job. One issue though, there is still a problem with poor performance on the SVN source code browser. For example, when browsing the GWT trunk source, I get a bunch of 'Loading...' on expanded tree leaf nodes, which take a long time to resolve (sometimes never) and also tend to freeze up Firefox's UI.
Thanks for sharing.
Yahoo's YSlow is quite useful for debugging these. I personally was very happy when I followed the rule of spreading static content over several domains, so browsers will open more sockets to your server.
OK ... now you've got Steve working for you are we going to have to hear this coming out of the Google camp every other day ... Why don't you just put an offer in on Yahoo! ...
Interesting.
I spent some time looking for a place to report issues with google code. I didn't find it. Can you please tell where can I report bugs?
what? are you suggesting that concatenating many images into a single image has a noticeable effect as compared to an http 1.1 persistent connection and is worth the trouble and maintenance nightmare that is the horrible looking image code you showed? not to mention the browser cache that shouldn't have to download those images more than once if you have the correct settings on your server....
I don't think I buy that one.
everything else seems cool tho.
szczepan faber-
Please feel free to report issues with Google Code at http://code.google.com/p/support/issues/list
Thanks!
Jacob
If only the blogger folks took some hints from you guys and made performance a priority for once.
Post a Comment