Optimizing Yahoo! Search for the iPhone

August 28, 2008 at 2:00 pm by Ryan Grove | In Development | No Comments

Ryan Grove, Frontend Engineer on Yahoo SearchRyan Grove is a web developer and part-time getaway driver (the former for Yahoo! Search and the latter for pretend). During the day he works primarily on Search Assist, iPhone Search, frontend architecture improvements, and performance; at night he writes open source software and occasionally sleeps.

When we set out to build an iPhone-optimized version of Yahoo! Search, we wanted to bring SearchMonkey, Yahoo! Search with Search Assist, tailored for the iPhone.
Search Assist, and other JavaScript-heavy Yahoo! Search features to the iPhone, but we also wanted the site to be blazing fast even over EDGE, all while reusing as much existing code as possible in order to minimize engineering effort and make maintenance easier. This is how we did it.

Reduce

Our first task was to remove code that wasn’t strictly necessary for the iPhone experience. We were able to eliminate a significant portion of the Search Assist code, and we shaved off even more bytes by rewriting the remainder in an iPhone-specific way rather than the generic, framework-like style of the original code.

Some examples of the kinds of things an iPhone-specific site doesn’t need:

  • Keyboard navigation and shortcuts: The iPhone doesn’t have arrow keys and the keyboard only appears when a text input element has focus, so code that handles keyboard shortcuts and navigation events is unnecessary.
  • Hover states and mouse movement handlers: Since the iPhone is a touchscreen device, there’s no mouse cursor and thus no way for the user to hover over an element. Mobile Safari fires the mousemove and mouseover events just before the mousedown, mouseup, and click events, and it fires the mouseout event when an element loses focus.
  • Context menus: There’s no way to right-click or control-click on the iPhone, so the contextmenu event cannot be triggered.
  • Text selection and clipboard handlers: Sadly, the iPhone does not provide clipboard functionality or a way to select text in an input element, so these handlers are useless.

Rewriting this code instead of reusing the existing code was a tradeoff since it meant we would need to spend more time maintaining it in the future, but the performance gains were worth it: we brought the minified JavaScript weight of the iPhone Search Assist implementation down from 32KB to 2KB (before gzip). Execution speed was also greatly improved by eliminating animations and simplifying the code that requests search suggestions on each keystroke.

After cutting out the unnecessary code, the next step was to make our remaining code as small as possible. The YUI Compressor made this easy, and we were able to save additional bytes by refactoring our code to follow the advice given in Nicholas Zakas’s article Helping the YUI Compressor, which describes several things you can do to help the YUI Compressor generate even more compact code.

Consider the following example (for the sake of brevity, I’ve replaced code that doesn’t pertain to this example with placeholder comments):

YAHOO.namespace('Search');

YAHOO.Search.iPhone = function () {
  // ... private methods ...

  return {
    // ... public methods ...

    toggle: function (el) {
      if (YAHOO.util.Dom.hasClass(el, 'hidden')) {
        YAHOO.util.Dom.removeClass(el, 'hidden');
      } else {
        YAHOO.util.Dom.addClass(el, 'hidden');
      }
    }
  };
}();

The YUI Compressor will compress the original 359 bytes to 209 bytes:

YAHOO.namespace("Search");YAHOO.Search.iPhone=function(){return{
toggle:function(A){if(YAHOO.util.Dom.hasClass(A,"hidden")){
YAHOO.util.Dom.removeClass(A,"hidden")}else{YAHOO.util.Dom.addClass(A,
"hidden")}}}}();

We can compress this code even further by replacing the repeated reference to YAHOO.util.Dom with a local variable and by using the more compact ternary operator rather than an if statement:

YAHOO.namespace('Search');

YAHOO.Search.iPhone = function () {
  var YUD = YAHOO.util.Dom;

  // ... private methods ...

  return {
    // ... public methods ...

    toggle: function (el) {
      var className = 'hidden';

      YUD[YUD.hasClass(el, className) ? 'removeClass' : 'addClass'](el,
        className);
    }
  };
}();

This will compress to a mere 173 bytes:

YAHOO.namespace("Search");YAHOO.Search.iPhone=function(){
var A=YAHOO.util.Dom;return{toggle:function(C){var B="hidden";
A[A.hasClass(C,B)?"removeClass":"addClass"](C,B)}}}();

Optimizations like this are particularly important due to Mobile Safari’s cache limitations, which we’ll discuss a little later.

Reuse

Search Assist was the only JavaScript component that we rewrote for iPhone Search; everything else was reused wholesale with no modifications. Two things made this possible:

  • Mobile Safari is a highly capable browser that can do virtually everything its big brother can do.
  • Our existing codebase uses YUI heavily. Since YUI takes care of most cross-browser issues for us, the code works well on all A-grade browsers including Safari and, by extension, Mobile Safari.

One of the most important factors to consider when reusing existing code is that the iPhone’s processor is much slower than desktop processors; as a result, JavaScript execution can be tens or even hundreds of times slower. It’s a good idea to avoid complex animation, heavy DOM manipulation, and other CPU-intensive operations.

If necessary, refactor your existing code to allow animations to be turned off, use event delegation whenever possible to minimize your DOM event overhead, and always be sure to provide a tag name and root element to YUI Dom Utility methods like getElementsByClassName. You’ll see performance improvements in desktop browsers as well as Mobile Safari.

Recycle

In the months after the iPhone was launched, the Yahoo! Exceptional Performance Team (and others outside of Yahoo!) discovered that Mobile Safari doesn’t cache components larger than 25KB pre-gzip. This presents a bit of a problem for iPhone web apps using YUI since the core YUI components (YAHOO Global Object, Dom Collection, and Event Utility) weigh in at a combined size of just over 30KB. We wanted to minimize the number of HTTP requests we made, especially via EDGE, but we also wanted to ensure that our components were cached so the browser wouldn’t need to download them on every pageview.

The solution was a tradeoff: We split our components into cache-friendly chunks of less than 25KB. This results in a few additional HTTP requests the first time the user visits the site, but it ensures that the components are cached and don’t need to be re-downloaded for future pageviews.

The easiest way to do this is to use the YUI Dependency Configurator, which will automatically create ComboHandler URLs for the components you select. For example, if your iPhone web app requires YAHOO, Dom, Event, and the JSON Utility, you can break these dependencies up into two requests, each smaller than 25KB:

<script type="text/javascript"
  src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo/yahoo-min.js&2.5.2/build/dom/dom-min.js"></script>
<script type="text/javascript"
  src="http://yui.yahooapis.com/combo?2.5.2/build/event/event-min.js&2.5.2/build/json/json-min.js"></script>

One catch: the YUI Configurator will try to include yahoo-min.js in each generated URL since all YUI libraries depend on it. There’s no need to load this file twice, so be sure to manually remove it from all but the first URL you generate.

Rejoice

Thanks to Mobile Safari’s awesomeness, YUI’s abstraction of browser compatibility issues, YUI Compressor’s excellent minification routines, and ComboHandler’s ability to aggregate multiple components into cache-friendly chunks, it only took us two weeks to build Yahoo! Search for iPhone. The end result is snappy even on slow EDGE network connections.

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

Open Hack Day 2008: You’re Invited

August 28, 2008 at 11:39 am by Eric Miraglia | In Development | 2 Comments

As some of you may recall, Yahoo held a big Open Hack Day back in September, 2006, at which many entertaining things happened, including Beck playing a concert for assembled hackers on the Yahoo lawn. It’s been too long, but we’re doing it again on September 12 and 13. And, of course, you’re invited.

The focus of Open Hack is to get together with other hackers and build cool stuff, show off the fruits of your labor, and win fun and fabulous prizes. But the Friday developer-day sessions also provide a chance for us to share with you work we’ve been doing at Yahoo that may be of use in your own projects and hacks. Although we haven’t announced the full Friday schedule yet, I do want to let you know that there will be at least two YUI-focused sessions:

  • September 12, 3 p.m.: Matt Sweeney and I will be presenting an overview of the new YUI 3.x codeline. This will provide a good orientation to 3.x and insights about the transition from 2.x implementations to 3.x implementations.
  • September 12, 5 p.m.: Matt, Adam Moore and Satyen Desai will be giving a hands-on workshop building on YUI 3.0. Bring your laptop and be ready to write some code.

Other developer-day content that might be of particular interest to YUIBlog readers:

  • September 12, 11 a.m.: Flickr frontend engineer Ross Harmes on hacking with Flickr data sources.
  • September 12, 11 a.m.: ASTRA library engineer Allen Rabinovich on using Flash in your hacks.
  • September 12, 2 p.m.: Rasmus Lerdorf on using Yahoo APIs in PHP.
  • September 12, 4 p.m.: Douglas Crockford talking about JavaScript.

All times are provisional at this point, but reserve your spot on HackDay.org, check out the teaser below, and we’ll look forward to seeing you here at Yahoo in a few weeks.


[link to teaser video]

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

YUI 3.x Meetups/Discussions Next Week at Yahoo: You’re Invited

August 27, 2008 at 1:55 pm by Nate Koechley and Eric Miraglia | In Development | 1 Comment

Earlier this month, we released a preview of the next generation of YUI — YUI 3.x. We’ve already gotten a lot of valuable feedback from members of the YUI 3.x community forum; thanks to everyone who’s downloaded the preview and started evaluating the new APIs.

Next week, we’d like to invite you over for beer and snacks here at Yahoo! to meet with YUI’s developers and talk about the goals and strategies intrinsic to the project. The setting will be small and informal — no slides, just some code demos and some discussion about the project. If you can make it, we’ll also be looking to hear from you about how this new version of the library meets (or fails to meet) your current and emerging needs.

To make it as convenient as possible for Bay Area folks, we’re doing two meetups:

Follow the links above to Upcoming to reserve a spot and get directions if you’d like to join us. We plan to broadcast the Sunnyvale event on live.yahoo.com; details to follow here on the blog when we get closer to the event.

Hope to see you here at Yahoo next week.

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

What’s So Social about Sign-in?

August 26, 2008 at 1:51 pm by Christian Crumlish | In Design | 2 Comments

Signing into Buzz

Just recently I published a new pattern, Sign-in Continuity, to the Yahoo! Design Pattern Library. It could be filed under “Engagement,” a category we have internally but that hasn’t appeared yet here, but I decided to put it in the “Social” category instead.

The pattern is about making sure that a user’s momentum isn’t robbed when they want to participate in a community and have to be challenged for their login credentials in order to sign their contribution. The crux of the pattern is to preserve context and make sure the user is inconvenienced as minimally as possible so that the continuity of the experience is preserved.

This raises a legitimate question: What’s “social” about sign-in? I have two reasons for classifying this pattern that way.

One is that signing-in is an act of claiming one’s identity in a shared space. Identity is an important social pattern “parent” and we have a number of patterns related to identity in the works.

The other is that social sites have evolved some new engagement patterns (some positive, some negative) having to do with invitation, sharing, organic growth, and levels of involvement, and in this context signing in to participate plays a role.

This was, by the way, what we like to call a “peeve-driven” pattern. I was trying to comment on a social object at Yahoo! site. (I won’t say which one because the problem has since been fixed.) I was challenged to sign in, which was fine, but once I presented my credentials, I was returned to the site’s home page instead of to the comment box I had been working on. Oh noes!

Sometimes, a poor user experience can help us identify an antipattern (in this case, sign-in discontinuity or in the original Latin, participatio interruptus) — and then the antipattern points the way to the positive solution.

I’d also like to mention that my summer intern, Chris Hanrath, completed this pattern and prepared it for publication. Chris also spent a lot of the summer working on the pattern library site redesign that I can’t wait to unveil. Stay tuned!

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

IntervalCalendar for Date-Range Selection

August 22, 2008 at 7:52 am by Satyen Desai | In Development | 7 Comments

New YUI interval-calendar example contributed by John Peloquin.

John Peloquin, a developer for W. Hardy Interactive, Inc., graciously contributed a new YUI Calendar implementation called IntervalCalendar that we’ve incorporated into the basic YUI Calendar example set.

The IntervalCalendar class, defined in this example, allows users to select pairs of dates representing the start and end of a date interval. Applications which require interval selection, for example a hotel check-in/check-out date selector, frequently display separate calendar instances to select the beginning and ending dates of the interval. The IntervalCalendar provides an alternate solution, by allowing the selection of both dates within the same calendar instance. It’s most suitable for applications in which the beginning and ending dates fall within the span of a few days, so that the entire range falls within the calendar’s visible set of months.

Many thanks to John and Walter Hardy for the terrific example and for contributing to YUI.

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

In the Wild for August 21, 2008

August 21, 2008 at 1:50 pm by Eric Miraglia | In In the Wild | 1 Comment

It’s been a busy July and August for the YUI team, working on a preview release of YUI’s next-generation 3.x codeline and ramping up for the next release in the 2.x codeline — a release in which we’re focusing on bringing DataTable and RTE out of beta, adding a new Carousel Control (based on Bill Scott’s popular YUI-based Carousel), and more. In the meantime, there’s been a lot of YUI news out there…

Using YUI:

What did we miss?

Let us know in the comments.

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

A Closer Look at YUI 3.0 PR 1: Dav Glass’s Draggable Portal Example

August 15, 2008 at 8:24 am by Eric Miraglia | In Development | 12 Comments

YUI 3.0 Preview Release 1 was made available on Wednesday, and with it we provided a look at how the next major iteration of YUI is taking shape. Among the elements we shipped with the preview is a new example from Dav Glass, the Draggable Portal, which exercises a broad cross section of the preview’s contents.

The Portal Example in the YUI 3.0 preview release.

The Draggable Portal is a common design pattern in which content modules on the page can be repositioned, minimized, removed, and re-added to the page. The state of the modules persists in the background, so a reload of the page or a return to the page calls up the modules in their most recently positioned state. You see variations of this design pattern on many personlizable portals like My Yahoo, NetVibes, and iGoogle.

In this article, we’ll take a look under the hood of this example to get a richer sense of YUI’s 3.x codeline and the idioms and patterns it establishes. We’re just pulling out some specific code snippets to examine here, but you can review the full code source for this exampleand for 66 others — on the YUI 3 website.

Continue reading A Closer Look at YUI 3.0 PR 1: Dav Glass’s Draggable Portal Example…

Share and extend: Bookmark with del.icio.us | digg it! | reddit!

Next Page »
Hosted by Yahoo!

Copyright © 2006-2010 Yahoo! Inc. All rights reserved. Privacy Policy - Terms of Service

Powered by WordPress on Yahoo! Web Hosting.