Improving Homepage Performance

We recently overhauled the Zillow homepage to make it faster and even more modern and user-friendly. As a summer intern at Zillow, I had more fun than I could have ever imagined working on such a high-impact and high-visibility project.
As you’ve probably learned from Nathan’s recent blog post, at Zillow we measure performance in user-experience terms, analyzing performance across metrics that directly reflects a user’s perceived experience. On the homepage, we felt that an apt metric would be a mark fired upon completion of loading of the hero image. This means that upon painting of the hero image, the page feels ready to interact with and has completed loading from a perceived user-experience perspective.
During our recent homepage work, we blew past our initial goal of 25% improved perceived performance, making a 67% improvement!
With the new desktop homepage, we took a different approach to loading in the hero image than we had before. The original desktop homepage loaded the hero image using a Javascript module. This Javascript-based loading allowed us the freedom to create a fading marquee roll for hero images but, of course, required completion of the document prior to loading. With the new desktop homepage, we took the approach of the original mobile homepage, loading the hero image as a static background image. While this doesn’t give us the opportunity of a fading marquee roll, it does allow the rendering to occur before the document is necessarily load-complete and render-ready.
While CSS files are more often used for styling in the Internet world now, browsers parse through the document and asynchronously request files mentioned in the document. We can cut the wait time before the first byte of the hero image is received by reducing the amount of time for the browser to request that image. This is done by specifying the background image styling inline on the document, rather than in a CSS file. In other words, because the styling on the original homepage specifies the background image URL in a CSS file, the browser must parse the HTML file, parse the CSS file, and then request the image; with the new homepage, because the background image is specified in the HTML file, it can immediately request for the image (rather than waiting to complete the CSS parsing).
Modern browsers prioritize external requests to improve perceived user experience. We can use this to our advantage by tricking the browser into prioritizing the hero image. Normally, browsers prioritize image tags in HTML above background image requests. This is because, generally, image tags form more integral parts of the user interface than background images. To use this to our advantage, we requested the image as part of a hidden image tag and later included it as a background image. In code, the markup looked similar to the following:
<!-- Begin loading hero image as fast as possible --> <img src="defaultBackgroundURL" style="display: none" /> <!-- Hero Image --> <div class="marquee-static" style="background-image: url( + defaultBackgroundURL + )"/>
This enhancement on its own improved the time to request the image by 85%, reducing to milliseconds the time to first byte.
All images on the page have been compressed to about 85% compression, which has led to an overall 50% decrease in the number of image bytes transferred from the server to the client. This results in a decrease of overall page weight and overall page rendering times.
With these improvements, we were able to improve the hero image performance mark by 67%, or threefold! This improvement, causing a reduction in page weight and page rendering time, is resulted in improved user interaction, mobile load times, and better mobile battery usage.
The redesigned homepage has more content, especially below the fold. There is content on all three tabs and each set has images. There are also hero images for each of the tabs on desktop clients. Performance in this domain is not especially easy to measure — we can’t use a user timing mark because it’s dependent on the interaction of the user with the page.
Once the document has completed loading and important content has been loaded (specifically, everything that is displayed initially), the hero images are asynchronously loaded into the browser cache. This is done by making a request for the image and storing the image in a Javascript object.
Once the document has completed the loading of important content, the content below the fold for other tabs begins to load. This content is served using an AJAX request for the markup that is contained below the fold.
One might consider that if switching tabs and switching back to the original tab, the content for the original tab also needs to be requested asynchronously. However, the redesigned homepage intelligently decides which tabs to make a request for regarding content below the fold. In other words, the redesigned homepage has knowledge about the current tab and requests content for all other tabs (and when switching to another tab, saves the content from the original tab so another request does not need to be made). The homepage is also intelligent enough to know that although tabs may have different hero images or other content, if their below-fold content is equivalent, no further requests are needed. For example, upon landing on the ‘buy’ tab, the page knows that a request does not need to be made for the ‘sell’ tab content (this content is equivalent to below-fold ‘buy’ tab content). This cuts in half the number of AJAX requests made by the page for below fold content.
Once the content for other tabs is asynchronously loaded, we know that the below-fold content will contain images on desktop clients. That content is then parsed for images and the images are loaded asynchronously so that upon switching tabs, the images for other tabs are cached and can render immediately.
At Zillow, we always have — and always will — care about performance. We’re committed to building the world’s largest and most trusted vibrant home-related marketplace, and that starts with delighting our consumers with a product that we’re confident in and believe in.
As an intern with Zillow this past summer, I’ve been struck by how much this rings true throughout the company’s culture. Performance is a part of the product, and it’s important to delight our consumers with everything we do. I’ve been very surprised by the vast number of opportunities for performance enhancements, but I’ve been even more taken aback by the willingness of my teammates to help me think through various enhancements. We’ve got a saying at Zillow that “Z is a Team Sport” and it rings true in everything we do, including performance.
That being said, we’re working on making our product better and better, and if you’re interested in helping us give the power to the people, let us know.