I have recently come across these terms: optimistic, and pessimistic UI updates; for updates in UI, after user actions which also involve changes in the backend. Usually a corresponding API is hit through an AJAX call, and the corresponding CRUD operation is done in the backend.
Which option, out of the following, would you pick when considering an update in the UI, in such cases:
Instantly make the update in the UI, making the change look instantaneous; and being optimistic that your update would also get reflected in the backend
Show an "updating" state, until you receive a confirmation from the backend that the update has succeeded - Partially optimistic/pessimistic.
Or to go through a completely pessimistic way, only update the UI after you receive a success response from the server.
Which one would you choose, and why; and if you have chosen "Depends", can you expand upon your answer; your thought process while approaching this whole UI update thing?
Optimistic - to the extent user experience does not suffer and to the point of not being deceptive.
Optimistic updates are a lot harder than they might appear, and require very careful handling of edge cases - especially when concurrency is involved. Not handling these edge cases properly can result in very poor user experience or set incorrect expectations.
Hashnode's answer box, trello etc. are great examples where optimistic UI really improve the user experience. But when you are talking about complex collaborative apps or multiplayer games then things can easily get brittle. You don't want to allow users to optimistically kill an opponent who might have actually drifted away but the client did not get that information due to network lag. You can not expect people to respond well if you have optimistically incremented their score for an achievement and then reduce it later when you realize that the accomplishment was in fact claimed by someone else.
Some level of conservativeness is usually necessary to keep the expectations in check. This may be something simple as a nanobar, putting a mask over the section that shows aggregated values after a form submission or something as complex as an animation that zooms out and elegant restores a card back to its previous column if the column it was being moved to got deleted by someone else.
Then there are cases which lie beyond the scope of any optimism - bank transactions, shopping cart checkout, financial feeds etc. where showing any hint of success before the operation has actually completed can be treated as a deception.
Always be conservative. Assume your backend is going to be broken, and let the user know as soon as possible what's going on.
If I'm deleting entry from a list, I'll remove it instantly and immediately update the UI and then fire a delete request which will delete in the background and if it failed, re-show the list entry. Creating items, I'll add blank item, fire the request and then wait for its id and content to come back before allowing to fill in data. So mostly optimistic here.
I personally like "Optimistic Updates".
Instant feedback is always great and most of the times the update will succeed at the backend. So, IMO the best way to do this is to show instant feedback, but still wait for the server to respond in the background. In case you don't hear back from the server or it responds with some error code, you will rollback the UI changes and notify the user that the changes couldn't be applied. For example, when you write a new comment on Hashnode you see it in the UI instantaneously. If due to some reason the comment can't be synced with the server, the changes are reverted with a warning.
Of course, there are no pre-defined rules. Different architects and websites have different preferences and you should stick to what makes more sense in your app.
As a programmer, I selected "Updating" State: Partially pessimistic. It strikes a balance between the time I have to spend building it and the need to keep the user from leaving.
As a Trello user, I really like the way it updates the UI optimistically and makes it feel like everything is applied instantly, as if there is just magic instead of a back-end. It feel like it just works and sets my mind at ease, but most importantly, it provides a faster and less interrupted user experience. As far as I'm concerned, this is the kind of experience I want to provide to my users as soon as I have nailed down a good approach to achieving optimistic UI updates.
I voted "Depends". If the operation is typically fast, then I would go completely pessimistic. If the operation is known to take some time, I would probably go partially pessimistic. I don't think I've ever gone optimistic. I suppose there may be some scenario where that would be warranted, such as when using a distributed database that has eventual consistency.
It depends on the critical nature of the action being performed. It is a balance between UX vs. need for accuracy.
"non-critical" recommend => Instant UI Update: Completely Optimistic
Likes, shares, feed actions, etc are examples of instances where the UI can be optimistically updated.
In the event of a failure the user can be notified and the UI can be updated (if the user is still in the app...) to reflect the state of the backend system. In a few instances the updates might fail, and the user may or may not see the follow-up notification, but it's generally okay because the action being performed wasn't really that important. A few misses in a million transaction is acceptable.
"critical systems" recommended => Updating: Partially pessimistic
Cash transfers, submitting taxes, checking for an airline flight, are a few examples of places where an optimistic update is generally a terrible idea because a false positive can be very consequential to the user.
Even if only a few users are exposed to inaccurate successful confirmations in a high volume system, the negative impact to those users are potentially very significant. As an example, a customer misses a flight because the airline website UI said they were checked-in, when they really weren't, - the UI updated optimistically, but the backend transaction failed. In that instance, they would have a right to be really unhappy, and report a poor user experience.
What if you correct the 'optimistic' UI update with the real system status seconds later? There is no guarantee that a user will still be using the app or webpage in the event the UI is subsequently updated with a failure notification after the actually response is processed, so a chance will always exist that the optimistic and possibly inaccurate response is all the user sees.
So the safe choice here would be to display an "Updating" indicator to the user, and then change the UI to "confirm" the change when a response is received from the backend indicating that the action the requested was actually carried out (successfully or otherwise). The user is happy and trust in the system is maintained.