Yahoo! Developer Network Blog
« Previous | Main | Next »
September 22, 2009
Not Just a Pretty Face: Performance and the New Yahoo! Search
Today we announced the new Yahoo! Search Results Page, which ships with a wide array of rich new features. What you might be surprised to learn is that the new design is actually a little faster than the original. Through diligent use of modern performance techniques, we not only held the line on the total page size and number of HTTP requests, but we also made a number of improvements to the load time of the page. Now that you've seen the new search results page, let's walk through some of the performance considerations we used when constructing the new template.
Code Refactoring
Any sweeping design change like this is a great opportunity to refactor, and we took full advantage, rebuilding the Yahoo! Search page's HTML, CSS, and JavaScript foundation from scratch. If you think of the template as a shell that wraps the "10 blue links" in the center of the page, all the markup around the middle content well has been rewritten. This allowed us to get rid of old cruft and take advantage of quite a few new techniques and best practices, reducing core pageweight and render complexity in the process.
As just one quick example of what's new, our search page now uses CSS image flipping. Rather than including separate images in our sprite for up and down arrows, we actually only include a down arrow. To generate an up arrow for all A-grade browsers, we use vendor-provided CSS hooks:
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
The actual byte savings are small, but every little bit counts, and this was relatively easy to implement.
We also took this opportunity to improve page structure and accessibility. As far as we are concerned, the philosophy that you have to create a separate experience for accessibility is a fallacy; we believe you can write accessible markup without hurting performance. A key improvement in the new design is simply creating better document structure using <h1>, <h2>, and <h3>, which enables screenreaders to navigate the page more easily. We've also added some better keyboard interactions, such as making sure the first tab key press takes you directly to the search box instead of hitting navigation links, and enabling CTRL-SHIFT DOWN to jump past the header and sidebar and put focus on the first web result.
Data URI Images
The new design incorporates several subtle, repeating gradients, which look great but can be absolute performance killers. To help alleviate this problem, we took advantage of an obscure feature supported by all modern browsers called Data URI images. This technique enables you to embed the encoded data for individual images right into your CSS. The technique has been around for a while, but it's only recently become widely supported enough to use in production.
Data URI images enabled us to avoid the extra sprite weight associated with repeating gradients, while at the same time improving perceived performance by avoiding the "pop-in" effect that you sometimes see with template images. In a traditional CSS file that refers to external images, the browser loads the CSS, parses the CSS, and starts rendering the page. Any image references in the CSS spawn a new HTTP request. Depending on your connection speed, the page might have already rendered by the time the image returns, which causes the image to appear like it suddenly popped in to the page. Data URI images helped us eliminate the pop-in effect entirely and significantly reduce the number of HTTP requests.
To maintain backwards compatibility, we provided a separate gradient-only sprite for IE6 and IE7. This means that those browsers encounter slightly worse performance than more modern browsers, but the net effect is still an overall win. Of course, managing a split code base is a little risky. Many sites prefer to do this at runtime, using conditional comments or other techniques. In our case, the overall difference is actually pretty small — our build tools push the right static resources to our CDN, and our frontend does browser sniffing and swaps in the right CSS file.
Semantic Page Flushing
Rather than waiting until the server generates the entire page and then sending everything at once, we send the page to the client in three semantically meaningful chunks, which enables the browser to start rendering the page and requesting static resources more quickly.
- The first chunk includes the page header and search box, and is sent before we even request search results from the backend. This enables the browser to begin downloading static resources while our server is still processing the search request.
- The second chunk includes all the visible page content and ads, but no JavaScript. This enables the user to instantly begin scanning and interacting with their search results before the browser downloads and executes any Javascript code.
- The final chunk includes the JavaScript that adds rich but non-critical functionality like Search Assist and Search Pad.
The net effect is that the user sees the page loading and can begin interacting with it much sooner. By sending the browser the info it needs to download static components as early as possible, we also reduce overall round-trip time.
Note that the old design also used semantic page flushing, but not quite as aggressively. The key difference is that in the previous design, the first chunk only included markup up to the <head>. By refactoring how our backend logic works, we were able to push the chunk down into the <body> and include key visual components such as the page header and search box. By getting the visual markup started down the wire, this creates the perception that the page is loading, that "something is happening."
Lazy Loading
The core JavaScript and CSS used on the SRP now loads in two distinct chunks. The first chunk includes only the bare minimum CSS and JavaScript required to render 100% of search result pageviews, so that the base experience loads as quickly as possible. The second chunk includes additional (but heavy) functionality such as Search Assist and Search Pad. We also load additional chunks of CSS and JavaScript for shortcuts and other dynamic features only as necessary, ensuring that we never waste time loading code that we're unlikely to need.
As a search site, we can get away with heavy use of lazy-loading because the search experience is such a fundamental user experience on the web. When a user requests a search page, they typically scan and click very quickly. As long as we make that core experience as fast as possible, we can defer other components for later. If your site has some other usage paradigm, you have to be more careful; you can't lazy load components that the user wants to interact with right away.
Designers and Engineers Agree: Performance First!
Beyond the technical considerations listed above, perhaps the most important factor was our philosophy that performance is everybody's problem, at all stages. Our frontend engineering team started thinking about and planning for performance even before the designs were past the rough draft stage. This enabled us to give early feedback to our User Experience Design (UED) department and work closely with them as they refined their designs.
Our designers had already taken into account many performance concepts they had learned over the years, such as sprite optimization. However, the new design uses gradients far more heavily than the previous design, which can get expensive — particularly if you stretch the gradients vertically or horizontally across the page.
Fortunately, our designers brought these considerations to us early, and we were able to brainstorm with them about how to use graphical components more efficiently. Once our designers understood some of the techniques we wanted to use and some of the limitations we had, they were able to knock out some absolutely gorgeous designs that still fit within our performance constraints. After those initial meetings, at each stage in the design our UED team would ping the performance engineers to ensure that we stayed within our performance targets. This close collaboration helped keep us from having to be reactive about performance.
In other words, new tricks and performance techniques only get you so far. Thanks to countless hours of hard work by individual designers and engineers, the new Yahoo! Search Page delivers far more functionality and design components in an even faster package. And we're still working hard with our designer colleagues to make the search experience even more fast and engaging over the coming weeks and months. If you have any questions about Yahoo! Search and frontend performance, we welcome your feedback!
Ryan Grove
Yahoo! Frontend Engineer
Stoyan Stefanov
Yahoo! Performance Engineer
Venkateswaran Udayasankar
Yahoo! Performance Engineer
Posted at September 22, 2009 10:57 AM | Permalink
Comments
Congrats on a job well done Ryan, Stoyan and Venkateswaran!
The new Search is very fast and the design has improved significantly.
I'm glad you worte this blog post and especially like the last section, where you explain the process of designers and engineers working together.
Keep up the good work.
Suggestion for a next blog post: impact of the new design and improved performance on actual Search usage (# queries per session, ...).
- Aaron
Posted by: Aaron Peters at September 24, 2009 12:56 AM
Interesting stuff. I'm still digesting it.
I have no idea what you are trying to achieve with the Search Pad though. There might be a good idea in there somewhere, but the execution is so awful that I can't detect any merit in it at all. I mean, I don't understand most of the dialogues it throws up, nor do I understand what problem its trying to solve for me.
Posted by: Jonathan at September 24, 2009 5:44 AM
Venkat, Stoyan, and Ryan -- this is fantastic, very glad to see you putting ideas out there for the community. I like how you improved accessibility, user experience, and performance rather than considering them separate problems. Bravo!
What do searchpad or search assist buttons and UI elements do before the JS loads? Did you provide backup functionality?
Also, did the changes increase the total number of searches per session?
Nicole
Posted by: Nicole Sullivan at September 24, 2009 8:51 AM
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
And for Opera ?
And actually you don't save any byte doing this, and you make your website slower because it gives the client more processing to do.
Posted by: bohwaz at September 24, 2009 8:57 AM
What about Opera for up and down arrows ?
Posted by: Anthony Ricaud at September 24, 2009 9:05 AM
The rotate trick is very clever.
For arrows and talk bubbles, I've been playing with borders, which is kind of fun, uses zero images, and works on Opera (as well as IE6+, FF, Safari, Chrome). It would allow you to eliminate a filter for IE. http://oocss.org/talk.html
@bohwaz, have you seen their sprite? It is tiny, every byte counts. http://a.l.yimg.com/a/i/us/sch/gr4/srp_metro_20090910.png
Posted by: Nicole Sullivan at September 24, 2009 9:37 AM
Hi,
2 small usability issues:
- When I click "youtube" on the left menu, I'm presented with a video "snippet" where I can click play, which is fine, but I expect the same behavior when I click "flickr" too.
- Users are not going to spot "xxx search results of xxx" at the top of the left menu. 2 reasons: It's placed away from the search results, and looks like a title of the left section.
Other than that looks fine ... :)
Thanks,
Posted by: sorin stefan at September 24, 2009 9:50 AM
@Aaron: Thanks!
@Jonathan: You can read more about the intent behind Search Pad here: http://help.yahoo.com/l/us/yahoo/search/searchpad/. Or, if you're still not happy with it, you can disable it from the Search Preferences page.
@Nicole: Thanks! We currently don't queue up click events for replay once the event handlers have loaded, but it's something we're considering for the future. In the meantime, wherever it makes sense, clickable elements have no-JS fallbacks which will also work when they're clicked before the lazy-loaded JS has been executed. I can't comment on Search metrics though, sorry.
@bohwaz: The sentence in the article about rotation being supported in all A-grade browsers is a mistake, sorry; it should have said *most* A-grade browsers, Opera being the exception. The rotation CSS actually does save bytes compared to including a rotated image in the sprite (remember, with an image in the sprite we would still need additional CSS to set the background-position), and since the CSS is only applied when a menu dropdown is actually clicked and not when the page is loaded, we don't suffer any runtime performance hit at page load time, which is what's most important.
@Anthony: Opera unfortunately doesn't support CSS transforms, so we weren't able to provide this feature for Opera. However, as with our IE6/7 gradient image tradeoffs, we're willing to make certain browser-specific tradeoffs if the overall benefit to other browsers is worth it. Opera is generally excellent, so this was one of the only Opera-specific tradeoffs we've had to make.
@sorin: Thanks for the feedback. I'll make sure it gets to the right folks.
Posted by: Ryan Grove at September 24, 2009 10:10 AM
Hey, hiya Nicole! :) So if you load the page and click very fast, and you don't have anything cached, rich features like Search Assist and Search Pad won't work... at least not instantaneously. Note that the vast majority of users who click super-fast are clicking on an algo link above the fold -- they're not pausing long enough to think about clicking on assistance features. This really just speaks to Ryan's point about what kinds of lazy-loading a search engine can get away with, versus say a browser-based word processor or music player.
bowahz, Anthony - The up/down arrow graphics do work in Opera.
Sorin - Thanks for the feedback! So for Flickr, if you're referring to searches like http://search.yahoo.com/search?p=flowers+site%3Aflickr.com+slideshow -- the slideshows do load & play, although the thumbnail graphics we have, errr, could be a little better. Or were you referring to something else? As for "xxx search results for yyy" -- there was definitely some debate about where to put this. I'll make sure to let our designers know.
Thanks,
Evan Goer
Yahoo! SearchMonkey Team
Posted by: Evan Goer at September 24, 2009 5:18 PM
I have lost my entire address book (contacts) and cannot find it. I have appealed for help but get NOTHING!
Why is there no one at Yahoo that can help?
Posted by: William Willis at September 25, 2009 11:51 AM
William, I've opened a support ticket for you. You should be contacted shortly by Yahoo! support, but if you are not, please let me know.
Posted by: Robyn Tippins at September 28, 2009 1:27 PM
You mention "they were able to knock out some absolutely gorgeous designs that still fit within our performance constraints".
Can you share what your performance constraints are? I'm guessing the old days of "pages must be under 100k total" or whatever the old axiom was are kind of gone. I'm curious what the goals are of a major web property are in this time of advanced features and broadband.
Posted by: Aaron Barker at September 29, 2009 6:10 AM
Faaast. Well done :) I'm an Opera user, but I understand holding back features for a 1% UA doesn't make sense (and it's not like anything's broken in the browser). Even Opera needs some nudging to keep with the game...
Posted by: Steve Clay at September 29, 2009 3:37 PM
Congrats on a job well done Ryan, Stoyan and Venkateswaran!
Search is Made fast and Easy,Design has made powerful.I'm happy That I had chance to give comment to this great post. this post is extremely useful for designers and engineers.I think so that this post is very much valuable for one's all round development.Yahoo is great and it will remain great.
Keep it up.
Posted by: adaptateur at October 12, 2009 12:32 AM
Post a comment
Comment Policy: We encourage comments and look forward to hearing from you. Please note that Yahoo! may, in our sole discretion, remove comments if they are off topic, inappropriate, or otherwise violate our Terms of Service. Fields marked with asterisk '*' are required.
Subscribe
Recent Blog Articles
view all
YQL Open Table for Google Buzz now live
Tue, 09 Feb 2010
INSERT INTO twitter.status ...
Mon, 08 Feb 2010
Announcing the Yahoo! Brasil Open Hack Day 2010, 20-21 March
Mon, 08 Feb 2010
Marketing hacks, linchpins, and tech women of valor
Sun, 07 Feb 2010
Yahoo! India invites you to join the first India Hadoop Summit
Thu, 04 Feb 2010
Recent Links
Appcelerator Titanium + Yahoo YQL on Vimeo
Mon, 08 Feb 2010
Tue, 02 Feb 2010
PhoneGap | Cross platform mobile framework
Sat, 30 Jan 2010
Web developers can rule the iPad - O'Reilly Radar
Sat, 30 Jan 2010
rc3.org - Is the iPad the harbinger of doom for personal computing?
Thu, 28 Jan 2010
Archives
2010
2009
2008
2007
2006
2005
Recent Readers

