Monday, November 15, 2010

Instant Previews: Under the hood

If you’ve used Google Search recently, you may have noticed a new feature that we’re calling Instant Previews. By clicking on the (sprited) magnifying glass icon next to a search result you see a preview of that page, often with the relevant content highlighted. Once activated, you can mouse over the rest of the results and quickly (instantly!) see previews of those search results, too.

Adding this feature to Google Search involved a lot of client-side Javascript. Being Google, we had to make sure we could deliver this feature without slowing down the page. We know our users want their results fast. So we thought we’d share some techniques involved in making this new feature fast.

JavaScript compilation

This is nothing new for Google Search: all our Javascript is compiled to make it as small as possible. We use the open-sourced Closure Compiler. In addition to minimizing the Javascript code, it also re-writes expressions, reuses variables, and prunes out code that is not being used. The Javascript on the search results page is deferred, and also cached very aggressively on the client side so that it’s not downloaded more than once per version.

On-demand JSONP

When you activate Instant Previews, the result previews are requested by your web browser. There are several ways to fetch the data we need using Javascript. The most popular techniques are XmlHttpRequest (XHR) and JSONP. XHR generally gives you better control and error-handling, but it has two drawbacks: browsers caching tends to be less reliable, and only same-origin requests are permitted (this is starting to change with modern browsers and cross-origin resource sharing, though). With JSONP, on the other hand, the requested script returns the desired data as a JSON object wrapped in a Javascript callback function, which in our case looks something like

google.vs.r({"dim":[302,585],"url":"http://example.com",ssegs:[...]}).

Although error handling with JSONP is a bit harder to do compared to XHR (not all browsers support onerror events), JSONP can be cached aggressively by the browser, and is not subject to same-origin restrictions. This last point is important for Instant Previews because web browsers restrict the number of concurrent requests that they send to any one host. Using a different host for the preview requests means that we don’t block other requests in the page.

There are a couple of tricks when using JSONP that are worth noting:

  • If you insert the script tag directly, e.g. using document.createElement, some browsers will show the page as still “loading” until all script requests are finished. To avoid that, make your DOM call to insert the script tag inside a window.setTimeout call.
  • After your requests come back and your callbacks are done, it’s a good idea to set your script src to null, and remove the tag. On some browsers, allowing too many script tags to accumulate over time may slow everything down.

Data URIs

At this point you are probably curious as to what we’re returning in our JSONP calls, and in particular, why we are using JSON and not just plain images. Perhaps you even used Firebug or your browser’s Developer Tools to examine the Instant Previews requests. If so, you will have noticed that we send back the image data as sets of data URIs. Data URIs are base64 encodings of image data, that modern browsers (IE8+, Chrome, Safari, Firefox, Opera, etc) can use to display images, instead of loading them from a server as usual.

To show previews, we need the image, and the relevant content of the page for the particular query, with bounding boxes that we draw on top of the image to show where that content appears on the page. If we used static images, we’d need to make one request for the content and one request for the image; using JSONP with data URIs, we make just one request. Data URIs are limited to 32K on IE8, so we send “slices” that are all under that limit, and then use Javascript to generate the necessary image tags to display them. And even though base64 encoding adds about 33% to the size of the image, our tests showed that gzip-compressed data URIs are comparable in size to the original JPEGs.

We use caching throughout our implementation, but it’s important to not forget about client-side caching as well. By using JSONP and data URIs, we limit the number of requests made, and also make sure that the browser will cache the data, so that if you refresh a page or redo a query, you should get the previews, well... instantly!

40 comments:

  1. i use browser flock, instant preview its show, but when i used mozilla, it doesn't appear, i know this issue on Tuesday, October 5, 2010 :) great feature! i like it

    ReplyDelete
  2. Amazing feature, I just love the idea, it will(I think), be great if internal search of sites, incluide it and the instant search!!

    Thanks Google Team!!

    ReplyDelete
  3. Might be a stupid question, but why don't you just return a jpeg from the server?

    ReplyDelete
  4. Dear sirs, perhaps you can write a little bit about the implementation of the setting to disable this evil feature, as the option is so intelligently placed that my meagre mind cannot locate it.

    ReplyDelete
  5. Strange that you mention Opera in the post. Opera is blocked from Google Instant and thus the page previews. When you identify as Firefox, everything seems to work flawlessly however so I can't figure out what the deal is.

    Any clue as to why Opera is blocked and when it will be fixed?

    ReplyDelete
  6. Really nice post!
    Informative and interesting to read about the available options and the reasons for choosing one solution over another. Things like this make me happy...

    ReplyDelete
  7. Well I'm just curious why would anyone want an option to disable it - can't you just not click on the 'magnifying glass' icon? It does not seem like it's adding any overhead to search results page unless you click on it...

    ReplyDelete
  8. Fantastic Feature! Any change of it being released as an api?

    ReplyDelete
  9. @Martin, did you read the article? It clearly explains why they are not returning images from the server.

    ReplyDelete
  10. I'd love to be able to click on the image and be taken to the specific part of the page that has the search result... especially useful for long pages

    ReplyDelete
  11. As always, fantastic information. I already added the timeout and src = null tips to my javascript library.

    Thanks for sharing!

    ReplyDelete
  12. @said - turn the feature off by going to google.com. At the right side of the "search" button, you will see "instant is on" link. Click that, and choose "instant is off". Be forewarned, however, that choosing this option will cause the page to update instantly (ironic), reverting to google.com homepage.

    Other effects of "instant off" are removal of the submit-the-search-form-as-you-type feature. The browser's default keyboard navigation will also be restored, allowing scrolling via the arrow keys in most browsers.

    @artem "Instant off" will appeal to those who favor keyboard navigation for scrolling. This should include many, if not most laptop users. It will also naturally appeal to those who like the search results to not change automatically as they type.

    Perhaps a proportion individuals who want "instant" off (which may exceed that which was anticipated by the designers of these features) will figure out how to turn it off.

    ReplyDelete
  13. Only problem with instant search is that when you try to leave the page you get the "Hooba! You've got text in an input field, you sure you wanna leave?"

    Which is totally annoying.

    ReplyDelete
  14. @Garrett That turns off instant search, not instant previews. I wouldn't have a problem with instant preview if it behaved as described and only activated when the magnifying glass was clicked. The problem is that it activates on any click in a search result, making it impossible to select words by double clicking, or do what I usually do, double click and drag to easily select whole words, without annoying popups appearing.

    The previews seem to be a useless gimmick providing no added value. I just want to get rid of them completely.

    ReplyDelete
  15. @mlug Yep you're right about turning instant off -- that doesn't turn off the preview feature.

    And you're right about clicking anywhere in the search result to activate the preview. If that is not by design, then it should be changed so that it is activated by magnification only. And when the window is not wide enough then the preview will overlap search results, causing a pretty serious usability problem.

    When instant is on, though, their kbd navigation activates focus which activates preview, which also triggers the preview-overlaps-search-results problem.

    I agree that clicking a search result should not activate preview -- that action should be taken on clicking the icon only.

    I don't like instant, so I can keep it turned off and then won't be bothered by any of the frills.

    ReplyDelete
  16. I agree with @mlug and @Garrett:
    I wish it would only activate after I clicked on the magnifying glass icon. I also activate it accidentally all the time (by clicking in the white space of a search result), and it does occasionally occlude other search results (not everyone runs on a 30" monitor). :-)

    Thanks in advance for looking into this.

    ReplyDelete
  17. To add to my previous comment... another reason why it surprises me is because the white space of a search result doesn't change your mouse cursor from the default. Usually, only hand cursors will trigger actions. In this case, the default text selection cursor or pointer will trigger the popup.

    ReplyDelete
  18. What the hell is wrong with google these days? They used to be cool.

    * They added sidebar which is good only for wasting my screen with useless informaion. Of course UI genius at google are not aware of splitters and "hide/display" buttons.

    * Instant search loves to mess with results. Google "I hate", append "you, google". Turn instant search off. OMFG! Shiny ajaxish google failed to pass your most recent search. Be happy with "I hate". Or even more ancient entry if you are lucky enough.

    * now this. It wastes my traffic, it wastes my screen once again. Once again genius decided that this feature should not be optional.

    I switched to google from yahoo for a reason - yahoo wasted my traffic and screen space just like google do it now.

    And for the same reason I'm leaving google for DDG.

    ReplyDelete
  19. Cool feature....

    Do we have an api for this??

    ReplyDelete
  20. great,.. love that tech is moving forward,. but how do I turn it off!!! and I how do I turn off the image preview zoomy thingy!

    ReplyDelete
  21. great article, with some great insights to how it's all done so quickly.

    One questions, when you grab an image do you wait for the page to load on the site then grab the image, or grab the image after x second regardless if the page is loaded or not.

    ReplyDelete
  22. Might be a silly question, but what about browsers that don’t support data: URIs, like IE7 and IE6? Do you use MHTML for that case or do they just not get the Progressive Enhancement goodness that is Instant Previews?

    ReplyDelete
  23. I accidentally stumbled on this feature earlier and I was pleasantly surprised. It's interested that you chose to highlight the relevant content in the instant preview. Well done.

    ReplyDelete
  24. For god's sake, stop turning it on when you click anywhere near the search results, and allow permanent opt-out without signing in with an account. This is Snap.com all over again.

    Btw, posting a comment here is ridiculously complicated.

    ReplyDelete
  25. Please let us turn of the damned thing off. I've gotten to the point that I've switched all my defaults to Bing, and trust me, that's not where I want to be right now.

    ReplyDelete
  26. +1 please turn this off.

    I am using resolution 1280 X 800 now and Firefox default font size "22". The preview is overlapping and hiding the search results. What good is a search result if I can't see it?

    I get that your developers use a high res desktop monitor and don't use keyboard navigation. But who is the feature designed for? Besides your developers?

    I have also noticed more than once that the preview comes on mouseover and so when I am reading, my thumb brushes trackpad and the preview pops up and abruptly obscures whatever I was reading or scanning.

    I am going to try other search engines.

    ReplyDelete
  27. Finding search.yahoo.com unreadably small (font-size: 13px), back with google search and now the preview popping up is an advertisement?!

    At first I thought it was a bug, but it appears that preview is sometimes and ad and sometimes a preview of the site.

    Again, preview gets in the way, overlapping search results when I mouse over (hasn't this been covered enough?). I don't want it. I don't want the ad or the preview and I don't want anything popping up when I click on the search results and I especially don't want anything to pop up on mouseover.

    I just want to search, click on a link, go to the site. That's it.

    When the ad preview fails to load, a blank, white box is displayed. Either way -- ad or white box -- who in the heck would want something like that?

    Who of anybody would want pop-up ads?

    With instant off, I am able to use the arrow keys to scroll the window, but still I get the ad preview, not only by clicking the text description in search results text but on mouseover of that text.

    Setting `script.src=null` is benign silliness; but features such as this are very harmful to the search page.

    Is there any plans for an option for "just search"? Because that's what I want -- no more, no less.

    I think you should really take it seriously.

    ReplyDelete
  28. To disable it, you need the greasemonkey add-on, and use a couple scripts to get rid of the annoying stuff. (I've seen google folks say a number of times that you have to click on the magnifying glass - and then no response once someone mentions that you can click anywhere on the search text div) Apparently, none of the developers believe us.

    Unfortunately, I'm on a different computer today, so I don't have the greasemonkey scripts I wrote to fix it. I can now see google without the sidebar, star and magnifying glass, and the preview doesn't show up when you click on the search result - it's great, and a much plainer and faster site than the default.

    ReplyDelete
  29. These instant,sugggest and autocomplete creating stuff are nothing more that socialist maneuvers to add more control over what WE can see, search and get. I prefer a plain Search that would take a litle bit more, but will give me the choices I looking for. Beware of this if you want to keep your real freedom of choice.

    ReplyDelete
  30. I'd be interested in knowing what you are using to generate the preview images/thumbnails/screenshots in the first place?

    ReplyDelete
  31. Can I beseech you guys to turn off the preview? I click anywhere on the text and the preview pops up, HIDING my search result.
    I do hope you see the idiocy of this?

    PLEASE turn it off. Its annoying enough for me to try Bing

    ReplyDelete
  32. @Osseta so, why can't they make 10 calls for the 10 images (jpeg/png, etc...) and 1 extra call for all the snippets and then combine them when displaying? Sounds like overkill, esp. when browsers will aggressively cache images too.

    ReplyDelete
  33. Are we allowed to request previews for our applications via an api... is this the right place to get an example of how to do it? Or is this just telling us how Google have done it for themselves?

    ReplyDelete
  34. I agree with what Kelvin said. I would like to access this as an API for use in my own Apps.

    ReplyDelete
  35. It would be nice to have an API to get previews of sites...

    ReplyDelete