Published: 15 May 2009
By: Dino Esposito

Dino Esposito discusses the Predictive Fetch pattern.

Contents [hide]

Introduction

In the beginning, users of (Web) applications were happy if only they could use the computer to automate certain tasks. Today, users reclaim an effective and pleasant experience as they navigate to and within a site. AJAX is mostly about making the Web user interface highly responsive with the primary purpose of improving the quality of the user’s experience.

In this context, the word “experience” is not a lightweight term.

Experience doesn’t just imply a UI that passively responds to user’s solicitation. When we target a better “user experience”, then we should aim at writing code that, to some extent, tries to understand what the user is doing and guesses what he or she might want to do later. There are many ways to give users a better experience, and some are application-specific. You offer a better experience if the application can respond to user actions quickly, if not instantaneously. Being more responsive, however, doesn’t mean that less data is being sent across the wire or that faster responses are generated on the server. Being responsive means getting users any requested data timely and quickly—regardless of the way you can obtain that and the space and time complexity it takes.

A behavioral pattern, the Predictive Fetch pattern helps you work out a solution to improve the user experience regardless of network and server conditions.

Although the Predictive Fetch pattern is often associated with Web and AJAX solutions, it should be intended as a quite general, platform-agnostic pattern. This said, the pattern fits very nicely in the context of Web 2.0 applications.

Prediction of the Next Action

Many actions that originate around a Web application require a response from the server and, subsequently, a roundtrip. The time it takes a request to terminate is known as the Time-To-Last-Byte (TTLB). TTLB is influenced by two main factors: latency due to data transfer and server processing overhead.

The classic approach to programming would try to smooth the impact of these two factors through specific code and network configuration. You just try to make the request complete faster—whatever that means—and you don’t start worrying about the request until it is made. Making a request complete faster is much easier said than done; and is not something that can happen for sure. Are you sure you can really speed up any request? And, if so, why didn’t you do it the first time?

The Predictive Fetch pattern drives you to a more comprehensive solution that offers a better experience regardless of the network and code details. The idea behind the pattern is just predicting the next user actions and preloading some of the data that it will be necessary to show later.

Downloaded asynchronously in the background, possibly during idle time, data is cached on the client using some JavaScript data structures. Next, when the user triggers the action for which that previously cached data is required, some client-side code retrieves and uses it to refresh the user interface as appropriate. In the end, the Predictive Fetch pattern is a sort of context-sensitive, client-side cache that requires a well-defined strategy about what to download and when to download it.

In a Web application, the main hurdle on the way to full user satisfaction is the usually long waiting time for results to be visible and consumable. Ideally, responses should be displayed in a range of time that is below the level of human consciousness, or at least very close to it. This means displaying results in just a handful of milliseconds. Is that really possible in a Web scenario?

Refreshing the user interface in ten milliseconds or so is clearly possible in a Windows client, but it is hard to happen over the classic model of Web applications. If a roundtrip is required, be prepared to wait also for a few seconds for the response to come back. This overhead is all part of the game and can be overcome only resorting to smart design tricks.

Predictive Fetch in Action

Imagine a Web page where the user can pick up a customer name from a list and then click to display details such as address and orders. Probably the user will spend some time looking at the customer details before turning her attention on orders. A good strategy to implement would then be betting on this behavior and retrieving orders immediately after displaying customer details, as the program is idle. In this way, it is likely that when the user focuses on orders, all information is already on the client and only one click away.

Retrieving the customer information is an operation that can be implemented in a variety of ways, including using ASP.NET partial rendering. The asynchronous retrieval of orders, instead, must necessarily be an out-of-band operation that is resolved via XMLHttpRequest. You organize the view in such a way the user gets personal details of a customer as soon as he selects a customer from the list. At the same time, you programmatically command a download of order information. Orders are downloaded asynchronously and cached locally. If the user later on decides to click and view the list of orders, any information is already in place and displays immediately.

The following code shows how to download information about a customer within an ASP.NET AJAX page.

The findCustomer function is bound to the click event on a UI element and runs as the user chooses to retrieve customer information. The function reads the currently selected customer ID and invokes a remote service.

The data retrieval occurs asynchronously and the OnSearchComplete callback is invoked when all details about the specified customer have been found and downloaded. As in the preceding code, the callback function populates the user interface with customer data and then triggers the download of orders.

Orders are downloaded in the background as the user consults the displayed information about the customer. The callback for the order retrieval operation updates the (hidden) portion of the user interface where orders will appear. Next, it will enable the button that provides access to that part of the user interface. When the user finally clicks on the orders button the list of orders is displayed instantaneously.

As an implementation detail, note that orders are retrieved directly as HTML markup. The remote service in charge of returning order information runs a query, formats data to HTML and then returns it.

Open Points

From a functional standpoint, predictive fetch is not such a hard pattern to implement and doesn’t pose high technical hurdles on your way. The real point with the pattern is all another—devising an effective strategy for the predictions.

You can’t pre-fetch just any data the user can possibly request and from any stage of the UI. You must be careful to cover the most likely actions and/or the most critical regardless of their likelihood. The strategy is the most important aspect of predictive fetch and it is not something that can be hard-coded in a recurring pattern solution. It is part of the architecture and belongs to the overall solution. The main drawback of predictive fetch is loading wrong data that will never be requested by the user. This creates unnecessary overhead and also may end up taking up some memory in the client computer.

Another point to take into due account is the overall behavior of the application that may appear to be sort of inconsistent to the end user. Imagine two similar features in a page—one that supports predictive fetch and one that doesn’t. Clearly, when the user selects the one that doesn’t have pre-fetch she faces a much longer response time. When she selects the other function, the response time is immediate. This may be confusing and may contribute to create some negative feeling.

Predictive Fetch and Client-side Caching

With reference to the previous illustrative example, what if the user at some point gets back to the same customer? Should you download details and orders over and over again? Obviously, you should not. Client-side caching enhances the application by retrieving useful and frequently-used data quickly and without further roundtrips.

Client-side cache can be obtained in a variety of ways, including via cookies or leveraging browser-specific storage capabilities. However, even a simple in-memory JavaScript-based dictionary that doesn’t survive the current browser session is a huge step forward.

The jQuery library provides an excellent client cache implementation through the data function. Here’s how to rewrite the previous predictive fetch example to make use of a client caching mechanism.

The jQuery library associates a local data container with a DOM element. In this case, the DOM element of choice is named customerData and is simply the <div> tag that contains the HTML representation of the customer information. If you use different HTML element containers, then you can use the same key name to represent information in the cache.

Summary

At the end of the day, a predictive fetch is nothing more than just a guess. And, just like any guess, it can be right or wrong. The more you know the system, the more you can make balanced guesses where the chances of success are far beyond 50%. This is the gist of the Predictive Fetch pattern—a frequently used pattern in AJAX applications, but not a pattern for Web applications only.

For more information on AJAX design patterns, check out Chapter 6 of “ASP.NET and AJAX: Architecting Web Applications”, Dino Esposito, Microsoft Press, 2009.

About Dino Esposito

Dino Esposito is one of the world's authorities on Web technology and software architecture. Dino published an array of books, most of which are considered state-of-the-art in their respective areas. His most recent books are “Microsoft ® .NET: Architecting Applications for the Enterprise” and “...

This author has published 29 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


ASP.NET Ajax Grid and Pager
Learn how to create a custom Ajax Grid and Pager with the Microsoft ASP.NET AJAX platform.
JSON-Enabled WCF Services in ASP.NET 3.5
Dino Esposito overviews the integration between WCF and AJAX
Using jQuery with ASP .NET
A brief introduction to jQuery and ways in which we can integrate it into ASP .NET
ASP.NET AJAX Control Development
An in depth guide to developing controls with the ASP.NET AJAX
ASP.NET Ajax Web Service
Sharing some of the Common Issues of ASP.NET Ajax Web Services.

You might also be interested in the following related blog posts


Calling the Twitter API in C# read more
Unit Testing - Do Repeat Yourself read more
Give a chance to prediction read more
Examining ASP.NET's Membership, Roles, and Profile - Part 15 read more
Update to Logging in to DotNetNuke from a Silverlight Application with RIA Authentication read more
Simplicity is key to successful unit testing - Part 2 read more
Don't be afraid of complex constraints read more
new Repository<T>().DoMagic() read more
new Repository<T>().DoMagic() read more
new Repository<T>().DoMagic() read more
Top
 
 
 

Please login to rate or to leave a comment.

Product Spotlight