Remembering state

Every time the user initiates an action on a website, a transition occurs from one state to another. Every URL (and query string) can be seen as a temporary state in a chain of events. A bookmark remembers the URL and allows the user to easily return to a site. This bookmark relates to a state from the history of the website’s existence, since the user already has an idea what the site was about, but doesn’t know exactly how it has evolved.

Remembering state is a usability enhancement that saves the user from doing repetitive work. Among others, we can keep track of the page the user came from (to go back if needed), the data he/she entered in a form before submitting it (to recover it if partially incorrect), the position of the last click (to undo part of a drawn figure), the scroll position of the viewport (to recover the last area of interest), the actions performed so far (to show the progress), the site-wide user preferences (to increase satisfaction). The state itself has to contribute to making the interface more immediate, not to store data for future marketing purposes. In other words, the state should be tied to the transition or storing it is probably wrong. A state shouldn’t be used to track visitors across websites, yet today’s sites are so intertwined that this could easily happen without the knowledge of the user. What is seen more worthy now aren’t individual states, but entire chains of events. This creates some significant challenges for the future when the history of collective online behavior will be available to all interested parties. Although collected once, the data will be analyzed by many during its lifetime and depending on the methods used, different insights will be extracted from it each time.

We should be able to recognize the structure behind the state. For instance, the structure of websites is hierarchical—the user comes through the main page, identifies topics of interest and seeks more specific information deeper in the hierarchy. If we have to restore a state, we’ll need to move up or down through a possible hierarchy of states. We may then seek to operate with the entire hierarchy instead of constantly choosing individual states. The relations between states can give us an idea of when it could be appropriate to combine them in order to create a more immediate state. In some cases states may even be able to provide semantic-like meaning to a page without actually hard coding it.

With states, all actions become undoable, which encourages more “crazy” exploration of an interface. Yet, the more states we have, the harder it becomes to return to a specific one, since the time to find it increases. And if someone did ten things wrong, it would be unwise to ask them to press some key combination ten times to undo the whole sequence. Another instance of using state in the wrong way is to embed the need for its modification in the interface—when the user, in order to continue, has to switch something on and off each time.

In some cases, states can be tied not only to actions, but also to the time when these actions occurred. If the user is able to go back in time, he may be able to undo all actions that happened after 2:34am yesterday morning. Some editors already support this, but it may be hardly replicable on the web where a user can click three times in a second. This is something that requires both fine granularity and unambiguity.

It pays to examine whether we can use states as interface cues—hints what the right action in the current situation could be. If so, we enable the user to more intuitively understand the interface and to minimize the time spent in thinking.

If we rely on a state being reachable, but this never happens, our interface won’t work correctly. We have to ensure that the presence or absence of a state doesn’t lead to unpleasant surprises.

If we combine multiple mechanisms to keep state, things can quickly become confusing. In most cases it would be best to choose a solution that works with the least amount of technologies. If we pick three different databases for keeping three different kinds of states, we are probably doing something wrong. Not only the data has a cost, but the mechanisms that are used to manage and access it every time. Over the lifetime of a project, the time we need to spend clicking on three different management interfaces can quickly add up. Any time we want to see our data, we need to go through different, sometimes quite heavy interfaces that are slow. We may choose to create our own simplified version that extracts and presents all the data in one place, but then we’ll need enough development time, which should preferably be less than our estimate on how long we would otherwise spend on clicks.

Remembering state in code is another word for caching or memoization. We don’t have to compute again the things, whose result we already know. By using the result directly, we speed up our code. This can be used in many cases, especially when looping over array elements or object properties, which we want to use for multiple operations.