Section 13.2. Predictive Fetch


13.2. Predictive Fetch

Anticipate, Fetch, Guess, Prefetch, Preload, Prepare, Ready

Figure 13-3. Predictive Fetch


13.2.1. Developer Story

Dave's tuning a music web site and the logs tell him that users who listen to a song for more than a minute are quite likely to click the Purchase button. So he introduces a new timerat the one-minute mark of each song, the browser will quietly download pricing data just in case the user wants to buy it later on.

13.2.2. Problem

How can you make the system respond quickly to user activity?

13.2.3. Forces

  • The application should respond to user actions quickly; ideally, it should feel instantaneous.

  • Many user actions require a response from the server.

  • Responses from the server can be noticeably latent due to data transfer and server processing overheads.

13.2.4. Solution

Pre-fetch content in anticipation of likely user actions. Pre-fetching attempts to remove the delay altogether for certain user actions.

The obvious motivation for instantaneous feedback is efficiency: the things can happen faster because the user's not sitting around waiting for results. In reality, though, the proportion of overall time waiting might actually be quite small. The more severe problem is distraction, because delays will break the user's concentration, along with the sense of frustration at not being in control. The other problem is that for real-time applications, the user is slower to respond to state conveyed by the server. A chat session will be more strained, and a remote device under browser control will be more erratic.

Here are some occasions when Predictive Fetch might be used:

  • The user's navigating a Virtual Workspace (Chapter 15) such as a large table. Pre-fetch the results of moving in each direction.

  • The user's converting between two currencies. Pre-fetch the major currency rates.

  • The user's reading some articles. Pre-fetch all stories in her favorite category.

Predictive Fetch usually requires a Browser-Side Cache (earlier in this chapter) in order to accumulate the pre-fetched content. In addition, you can exploit the web browser's built-in cache in a couple of wayssee Browser-Side Cache, earlier, for a comparison of these techniques. To get something in the web browser's built-in cache, one technique is to issue XMLHttpRequest Calls for content you'll need later on, using the techniques mentioned in that pattern to encourage the content to be cached. The response handler does nothing herethe point is simply to bring the content into the browser, where it will be cached for later on. The other technique is for images: create a dummy image (document.createElement("img")) object and set its src property to whatever image URL you want to preload. Again, we're only doing this to ensure the image goes in the cache, so the image isn't actually attached to the page.

It's rarely possible to pre-fetch for all actions, so the designer has to be smart about anticipating which actions are most likely. Higher priority will be given to content that is more important or more likely to be used.

One problem with pre-fetching is the application will be a bit erratic. The user might be surprised that some commands respond instantaneously, while similar commands take a long time. While some variation is always expected on the Web, the main problem comes when the data arrives immediately. The user will reasonably question whether the app was really taking their action into account (http://www.baekdal.com/articles/Usability/usable-XMLHttpRequest/). For that reason, a useful but counter-intuitive trick is to actually fake a small delay and use a visual effect like One-Second Spotlight (Chapter 16) to hint that the server really was involved.

13.2.5. Decisions

13.2.5.1. How much information will be pre-fetched?

Pre-fetching comes at a cost. Anticipating the user's actions is a guessing game, and for each guess that goes wrong, some resources have been wasted. Designers must make a trade-off involving the likelihood that pre-fetched data will be used, the user benefit if it is used, and the overhead if it's not used. This could involve some fairly heavy user analysis combined with statistical methods.

In practice, it's feasible to use some initial rules of thumb and proceed on a more empirical basis. With the right design, it should be easy enough to discriminately turn pre-fetching on and off. Thus, by studying logs and comparing the effects of pre-fetching different aspects, it's possible to evolve the algorithms being used.

13.2.5.2. Will it be the server or the browser that anticipates user actions?

The request for information will always come from the browser, but it's feasible for either the server or the browser to anticipate what the user will need next. If the browser is to decide, it can simply issue a request for that information. If the server is to decide, the browser can, for example, issue a periodic request for general informationperhaps with some indication of current stateand the server can then push down whatever information it decides might come in handy for the browser.

13.2.5.3. What information can be used to anticipate user actions?

It's likely you'll use some information about the present and the past to help predict the future. There's a lot of data you could potentially use to help decide what the user will do next:


User's profile

The user's profile and history should provide strong cues. If the user always visits the Books area as soon as they log on, then the homepage should pull down Books content.


User's current activity

It's often possible to predict what the user will do next from their current activity. If a user has just added an item to his shopping cart, he will likely be conducting a purchase in the not-too-distant future; consider downloading his most recent delivery address.


Activity of other users

Sometimes, a rush of users will do the same thing at once. If the user has just logged into a news portal while a major news event is in progress, system-wide statistics will inform the server that this user is probably about to click on a particular article.


Collaborative filtering

As an extension of the previous point, a more sophisticated technique is to correlate users based on information such as their profile and history. People are likely to behave similarly to those whose details are highly correlated. So if a user tends to look at "Sport" followed by "Weather," then the system should start pre-fetching "Weather" while the user's looking at "Sport."

13.2.6. Real-World Examples

13.2.6.1. Google Maps

Some experimentation with Google Maps (http://maps.google.com) suggests Predictive Fetch is used while navigating the map (Figure 13-4). The evidence is that you can slowly move along the map in any direction, and you won't see any part of the page going blank and refreshing itself. If you move quickly, you'll see the refresh behavior. Based on that observation, the map is apparently fetching content beyond the viewable area, in anticipation of further navigation.

Figure 13-4. Google Maps loading


13.2.6.2. map.search.ch

map.search.ch (http://map.search.ch) includes familiar buttons for zooming and panning. The difference is that at as soon as a mouse pointer hovers over a button, a call is made to anticipate the user clicking on it. This is a good compromise between downloading in every possible direction and zoom level or doing nothing at all.

13.2.6.3. Firefox "Prefetch"

This is not entirely an Ajax example, but it's worthwhile noting a particular Firefox (and Mozilla) feature called "prefetching." The HTTP protocol allows for new link types to be defined, and Firefox happens to define a "Prefetch" link type (http://www.mozilla.org/projects/netlib/Link_Prefetching_FAQ.html#What_is_link_prefetching). A "prefetch" link looks like this:

   <link rel="prefetch" href="/images/big.jpeg"> 

When Firefox sees such a link appear, it will generally fetch the associated content, which is ready to be shown immediately. An application can exploit that feature by including links to content that is likely soon to be requested.

Google Search, for example, slaps a prefetch directive around the first search result, but states that this occurs for "some searches" only. I am guessing, based on some experimentation, that this means searches where Google is highly confident the top search will be chosen. So a search for the highly ambiguous term "anything," results in no prefetch directive. Meanwhile, a search for IBM, where it's obvious what most users seek, will direct Firefox to prefetch the first result:

   <link rel="prefetch" href="http://www.ibm.com/"> 

13.2.6.4. International Herald Tribune

Another example is The International Herald Tribune (http://www.iht.com/), which caches entire articles to provide instant gratification when you click on Next Page.[*]

[*] This example is taken from an O'Reilly Network article (http://www.oreillynet.com/pub/wlg/6782).

13.2.7. Code Refactoring: AjaxPatterns Predictive Fetch Sum

The Basic Sum Demo (http://ajaxify.com/run/sum/) allows the user to enter a set of figures, but he must wait for the server in order to see the sum. The Cached Sum Demo (http://ajaxify.com/run/sum/xml/cached/) improves on the situation a bit, by ensuring recent sums do not need to be re-fetched. However, there is still no anticipation of user behavior. In this refactoring (http://ajaxify.com/run/sum/predictive/), a new sum is fetched each time the user types something. By the time he has pressed the Add button, the browser should hopefully have the result waiting in the cache, ready to be displayed immediately. Each time a new sum is anticipated, the browser fetches the result, and a callback pushes it into the cache.

The code change is actually fairly straightforward. As before, clicking on the Add button causes a server sum request. This time, though, a flag is set to indicate its a real user submission as opposed to a pre-fetch. The call will "remember" the flag; i.e., using ajaxCaller's callingContext, the flag will be passed to the callback function when the response is issued:

   $("addButton").onclick = function( ) {     submitSum(true);   } 

For Predictive Fetch, each release of a key triggers a sum submission, with the callback false to indicate this was not a user submission.

   $("figure1").onkeyup = function( ) { submitSum(false); }   $("figure2").onkeyup = function( ) { submitSum(false); }   $("figure3").onkeyup = function( ) { submitSum(false); } 

submitSum( ) will perform the same request as before, but this time passes in the flag as a calling context:

   ajaxCaller.get("sumXML.php", figures, onSumResponse, true, isUserSubmitted); 

The isUserSubmitted flag is then retrieved by the callback function, which will only change the display if the corresponding query was user-submitted. Either way, the result is then pushed into the cache for later retrieval:

 function onSumResponse(xml, headers, callingContext) {   var isUserSubmitted = callingContext;   ...   if (isUserSubmitted) {     repaintSum(sum);   }   ... } 

13.2.8. Alternatives

13.2.8.1. Fat Client

Sometimes, the server is invoked to perform some logical processing, rather than to access server-side data. If that's the case, it may be possible to process in JavaScript instead, as suggested by Fat Client (see later).

13.2.8.2. Server priming

In some cases, the reverse may be more appropriate: it might make sense for the browser to hint to the server what the user is working on, without the server actually responding. How is this useful? It allows the server to get started on processing, so that the required information can be cached server side but not actually pushed into the browser's own cache.

13.2.9. Related Patterns

13.2.9.1. Guesstimate

Guesstimate (see the next pattern) is another performance optimization based on probabilistic assumptions. A Guesstimate involves the browser guessing the current server state, whereas a Predictive Fetch involves guessing what the user will do next.

13.2.9.2. Browser-Side Cache

Browser-Side Cache (see earlier) is a prerequisite to Predictive Fetchthe predictively fetched data has to be stored in some form of cache.

13.2.10. Metaphor

Time-shifted mediaevident in Tivo, offline RSS readers, and podcatchersis an example of Predictive Fetch.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net