Accessibility

Table of Contents

Designing for Flex – Part 7: Making your application fast

Improving responsiveness

Sometimes applications are structured well—they focus on eliminating work and provide excellent starting points based on their users' goals and tasks—yet they fall down on more traditional efficiency concerns; the application is just too slow. Heavily-networked Flex applications can easily fall into this trap, for the Internet is a notoriously unreliable beast. This section focuses on how users' perceptions of performance impact their experience of using applications and how that should affect where you spend your design and development efforts.

When tuning application performance, focus on the functions where the actual speed is most at odds with what users expect the speed to be. Absolute performance metrics have no meaning when divorced from the context of user expectations; an O(n2) algorithm or a 10-second response time might be completely fine or unacceptably slow depending on how long the application's users expect the operation to take.

There are three distinct kinds of operations with very different associated levels of expected performance: physical changes, screen loads, and big jobs.

Physical changes are operations that appear to the user to be mere manipulations of interface objects. These should appear near instantaneous to users. Examples include dragging and dropping a photo from one list to another, expanding a closed branch of a tree control, changing the filter criteria of a list, and getting the highlight feedback when hovering over a button. A good rule of thumb is: if a browser page refresh would be undesirable between one state and the next, necessitating the use of AJAX or Flex in a browser-based application, then you're probably dealing with a physical change.

 Most state changes to standard controls are examples of physical changes, such as moving from the up state of a button to the down state when the user presses on it.

Figure 9a. Most state changes to standard controls are examples of physical changes, such as moving from the up state of a button to the down state when the user presses on it.

Drag and drop is another example of a physical change, since the user physically moves the object from one location to another.

Figure 9b. Drag and drop is another example of a physical change, since the user physically moves the object from one location to another.

Screen loads occur when the user first navigates to the application or when she moves to a completely different section (which should only occur when she begins work towards a new goal, see Part 3: Structuring your application). Screen loads usually need not be instantaneous, but they should take less than 10 seconds. The more time you take between one second and ten, the more motivation your users need to have to wait it out. If you structured your application well, users will be starting a new task whenever a screen load occurs, so a moment's wait is acceptable. An example of a screen load is when a user moves from the online bill pay system of a banking site to the investment services system.

Flektor performs a screen load after the user selects a quick start. When the user clicks any of the quick start options, the loading screen appears, then Flektor transitions to the screen with the appropriate quick start feature.
Flektor performs a screen load after the user selects a quick start. When the user clicks any of the quick start options, the loading screen appears, then Flektor transitions to the screen with the appropriate quick start feature.
Flektor performs a screen load after the user selects a quick start. When the user clicks any of the quick start options, the loading screen appears, then Flektor transitions to the screen with the appropriate quick start feature.

 


Figure 10. Flektor performs a screen load after the user selects a quick start. When the user clicks any of the quick start options, the loading screen appears, then Flektor transitions to the screen with the appropriate quick start feature.

Big jobs are long-running operations that users expect to take some time. Users request them infrequently and often only after much preparation. Big jobs can get away with taking longer than 10 seconds, especially if the user can run them in the background while getting other work done. Examples include report generation and aggregation of search results from multiple websites. Note that user expectations of what should take a long time change; it used to take hours to compile program code, nowadays it must take no more than a few seconds.

 Backup operations are a good example of a big job. Users carefully prepare for them, run them infrequently, and expect them to take a long time.

Figure 11. Backup operations are a good example of a big job. Users carefully prepare for them, run them infrequently, and expect them to take a long time.

Note that these types of operations run from high performance expectations to low. This implies that when seeking to improve responsiveness, you should start by examining the little physical changes in your application rather than the complex, long-running algorithms.

checkmark Focus performance tuning efforts on those portions of the application where the actual speed of operations is most at odds with user expectations.

Improving the responsiveness of physical changes usually means lots of caching. Slow network loads and complex calculations must not occur at the moment of physical change but at a time when speed is less important. There are two basic options: take the performance hit when the screen loads or run the operation in the background while the user is preoccupied with less performance-intensive tasks. The latter is particularly attractive as it allows you to perform time-intensive tasks without the user realizing anything is happening.

Both of these strategies suffer from a single barrier; you must anticipate what the user is going to do if you are to preload or precompute it for her. But this may not be as difficult as imagination makes it out to be. Oftentimes there are only a few commands users are likely to issue or content they are likely to view. If in doubt, consider computing everything and simply discarding any results that turn out to be unnecessary. Processors are already blindingly fast and networks are getting faster; both spend most of their time idle, ironically waiting until just the moment results are needed—when the user makes a request—before springing into action. By this time it may be too late to satisfy the user's performance expectations.

checkmark Pre-compute results while the application is idle and cache results to speed up future operations.

Sometimes, precomputing or preloading data is not an option; if your Flex application lets users search a large database, there may be little you can do until some search parameters are available since the database may be way too big to preload in its entirety. If the task will take more than a second, consider whether it can be broken down into smaller pieces to make it seem shorter to the user. For example, load and display search results bit by bit as they become available; the user can only deal with one screenful at a time anyway. You can employ this strategy to great effect with all kinds of otherwise sluggish physical changes.

checkmark Break down long tasks into smaller bits so that the results can be presented to the user as they become available.

Whenever possible, leverage the asynchronous nature of the Flash Player and the Internet itself to perform slow operations in the background while the user does other things such as viewing content and thinking. Although there may be times when you or your developers will need to break out the old algorithm performance analysis book, most performance gains in Flex applications come not from actually making things faster, but by moving work around so that the application feels faster to the user.