Page Loading and Rendering Optimizations

For an online shopping business of any size, time is quite literally money. For eBay, a delay of milliseconds is enough to make the difference between a purchase and a dissatisfied customer who abandoned a page that didn’t load as quickly as desired. Multiply that experience by eBay’s 100 million-plus active users, and you can see how even short delays can have significant financial impacts.

In this blog post, I present some of the techniques that we use to optimize the presentation stack for the eBay Marketplaces web site.

Measuring Above-the-Fold Time (AFT)

AFT is the time that elapses between the first and the last pixel change in the part of the browser window that you see without scrolling. Currently, there are no browser APIs to measure AFT. For today’s image-intensive web pages, image loading is a major contributor to AFT as well as to total page load time. If you know all of the images that will load above the fold, you can calculate AFT by measuring the last image loaded in the above-the-fold area. While not as accurate a measurement as pixel-by-pixel, this calculation can provide a useful estimate.

Here is JavaScript code you can use to calculate AFT, assuming that the first six images display above the fold. The ‘start’ variable holds the time of the first byte. You call the ‘measure’ function on the onload  event of the first six images, capturing the time for each in the lastImageLoadTime variable. On the window’s onload event, you simply subtract the start value from the lastImageLoadTime value to calculate the AFT. Irrespective of the load order of the first six images, lastImageLoadTime will hold the load time of the last of these images. This technique gives you a rough idea of how much time it takes to load all of the above-the-fold images.

<HTML>
<HEAD>
   <SCRIPT>
      var start = new Date().getTime();
      var lastImageLoadTime = null;
      function measure(){
         lastImageLoadTime = new Date().getTime();
      }
      window.onload = function(){
            alert("Above fold time = "+(lastImageLoadTime – start));
      }
</SCRIPT>

</HEAD>
<BODY>
   <IMG src="image1.gif" onload="measure();">
   <IMG src="image2.gif" onload="measure();">
   <IMG src="image3.gif" onload="measure();">
   <IMG src="image4.gif" onload="measure();">
   <IMG src="image5.gif" onload="measure();">
   <IMG src="image6.gif" onload="measure();">
   <IMG src="image7.gif">
   <IMG src="image8.gif">
   <IMG src="image9.gif">
   <IMG src="image10.gif">
</BODY>
</HTML>

We’re using this technique to measure and optimize the AFT.

Page rendering

So many factors influence page rendering. Today’s web sites contain lots of JavaScript, CSS, and images. The quantities of these resources and their placement within the HTML markup have a direct impact on page rendering.

JavaScript

When the browser parses the HTML markup, it stops rendering the HTML when it encounters an inline JavaScript block or external JavaScript file. At this point, the user experiences rendering delays. Moving the JavaScript to the end of the HTML markup would completely eliminate these pauses in rendering.

Here is a simple way to test how JavaScript is influencing the rendering of your page. Although you can use any browser for this test, the influence is easily detected using Internet Explorer. Launch Internet Explorer and open your web page. After the page is completely loaded, change the URL in the browser’s address bar to something else. Now click the browser’s back button. You should see the previous page instantaneously. If you instead observe any pauses in the rendering, you can definitely say that JavaScript is affecting page rendering.

Last year, we implemented this technique on the US, UK, and Germany search results pages. As a consequence, the usability, performance, and bottom-line numbers have improved greatly. Surprisingly, with this change alone we increased purchases by 1%. We also had very happy customers!

CSS

Treat CSS like a king and JavaScript like a slave. What I mean by this is to keep the CSS on top of the HTML markup and JavaScript at the bottom of the markup. Keeping the CSS on top optimizes HTML rendering and reduces the re-flows.

Images

Browsers have limited concurrent connections per domain. If your page exceeds the number of images that can be concurrently downloaded from a given domain, you will see delays in the rendering of those images. One work-around for this issue is to create more subdomains, thereby increasing the number of connections. Still, this approach requires a connection to download the images.

How about eliminating the connection altogether?  You can do so by embedding the image in the HTML using Base64 encoding, which is supported by most modern browsers. Limit the embedding to those images that will display above the fold, to improve the above-the-fold rendering.

Conclusion

This post merely touches on some of the techniques we’ve found that can make a real difference in the amount of time customers spend waiting on pages to load and render.  We’ll provide updates discussing more optimization techniques that we’re exploring.