The converse is pessimistic rendering: waiting for the server response before updating the UI (and possibly showing a loading spinner in the interim).
Facebook Messenger has the best UX paradigm for this I've seen, since it's most graceful in handling the edge case failures while still presenting as optimistic. Your message immediately appears as a conversation bubble, with an icon displaying if the server has received it, an 'X' if it fails (clicking the icon gives you options: re-send, delete, etc), and a read receipt for when the other party views the message. It's a fantastic way of handling the lifecycle.
Slack fails because it doesn't communicate that pending, the-server-hasn't-received-it-yet status, and the fallback isn't as graceful.
You post a message, it looks good, you move on.
Then later on you come back to it and it was never sent.
The only way I found to know that your message has been received is to have an ack from your interlocutor.
I hate the phrase "I'm a realist not a pessimist" as much as the next person, but isn't this actually "realistic rendering"?
"Optimistic" often means "assume X, perform or calculate something, change the result if X turns out to be false".
"Pessimistic" often means "assume not-X, perform or calculate something, maybe change the result if X turns out to be true".
This comes up in other domains.
For example in compilers (and reverse engineering decompilers ;-) there are optimistic and pessimistic analyses.
An optimistic analysis might initially assume a particular variable has a specific value at a particular location, or a branch is always taken. Then trace through the program paths, using that assumption (which limits those paths). If it loops back to the location with a different value in the variable or different value for the branch condition, broaden the assumption and update the trace.
A pessimistic analysis might initially assume the variable at a particular location could have any value because it hasn't yet traced everywhere to find out the possibilities, or initially assume both directions at the branch could happen and include them both in the trace. By the time it finishes tracing all paths and values, those assumptions may turn out pessimistic and it can start pruning away unused options.
These two strategies can yield different answers, and for some analyses the optimistic strategy gives more accurate results than the pessimistic strategy.
So which one is more "real"? :-)
FYI, Signal has used this paradigm for quite some time (I'm not sure which software predates the other on this feature), it's two checkmarks which remind me of the old "open Apple, closed Apple" keyboard keys - message bubble is shown with two open checkmarks right away, a single closed checkmark means the server has received, the second closed checkmark means the other end has received (assuming read receipts are enabled, Signal allows them to be turned off for privacy reasons).
It's easier than making the UI and server faster for sure, I'm just not sure why engineers don't insist of fixing things the right way.
That's like saying "just fix global warming", it's more complicated than that.
Einstein figured out why in 1907, and most of us have just been going along with the assumption that superluminal communication just isn't possible.
In majority of cases, I assume network latency will be the dominant factor, and that is outside the control of the engineers.
I happen to use slack from hardwired gigabit ethernet to a gigabit fiber internet connection. But I maintain some awareness that some others may use it from their older android phone with 2 bars of service, or on a laptop with 27 open blasting wifi spots, etc etc etc.
I will therefore put forward that assumption you can ensure instant communication, is the wrong wrong wrong way for engineers to write code...
Viber had a similar thing long before FB's messenger: single gray check mark character if the message is sent, double gray check mark if it is received by the recipient and double check mark in purple if it is seen.
The only issue is with the purple color of the "seen" as it can sometimes blend into an image behind it (if the message was consisting of an image).
If I post a message in a channel and go back to work, I don't want to find out later when I check for replies that my message didn't actually send - I need a notification!
I somewhat often send messages just before I have to run to catch the subway — and when I think the message got sent, I type `sudo poweroff`
There are other things to consider too. Like for example network failures vs backend failures. In the case of network failures you can actually notify users before they even try to take an action. So now you’re down to some diminishing case where your code is effectively wrong (maybe the client is too old), and again there are more elegant ways of handling that. Also, I bet you have the response back really quickly to make a call on it.
Having a worked on unstable networks I can say that there are parts of slack’s implementation that suck - like if you try to change a message that hasn’t synced yet, they get into broken states with the edit. But that’s not the fault of optimistic UI, it’s other technical choices at play.
I know you haven’t named a horse in this race, but I feel people hating on Slack for having an optimistic UI are a bit off base. Considering that I’ve sent (apparently) 2.5k slack messages in the last 30 days and I don’t recall any going wrong, I think they’ve got it right.
It's not a 1-3% failure rate for the backend, it's a 0.01-0.1% failure rate for each request between dozens of microservices each with their own bespoke error handling, each owned by a team with more political clout than the frontend guys/gals who keep reporting Sentry errors due to "UnknownNetworkError" or some other such nonsense, all wrapped in some spaghetti code frontend thats written like the whole thing is running locally.
Overall I strongly dislike this UX pattern. Users should have immediate feedback about actions that haven't completed, but that feedback should only tell them the truth: that the operation has begun.
There are trade offs to consider in UX. You’re trying to make things as seamless as possible for the end user without distracting them with things they don’t care about.
Even if the idea is to fool the user in to thinking Slack is faster than it is, the UI could at least use the reversed 'light grey until confirmed' UI once it's detected that there's a problem. That would make it a bit less tiresome.
At which point there is no option to cancel and say "you know what... don't send it".
If you notice it 24 hours later, your choices are (1) be nagged about retrying it forever or (2) retry sending a message that may now be irrelevant.
When it comes to retries, the easiest thing for the user is for the software to be responsible for retrying failed actions. Choosing not to do that makes sense IF the goal is to give the user more control because they may not necessarily still want the action done.
But if you don't give them that control, it's the worst of both worlds. The retry happens slower, with more manual work, and without the benefit of choice.
On mobile it means that I can't tell if this user has responded to a message or is online at all. I tried telling it not to send ages ago when it actually failed but it hasn't worked, and frankly now it's so far back in history it's impossible for me to try again.
I've deleted slack and re-installed to no avail. It's really an awful problem.
(I know this because I just spent 60 seconnds staring at my message trying to figure out why the formatting was off before it told me it wasn't sent. It sent immediately when I retried though.)
This morning alone, I've had multiple messages start off black, then turn grey after about 10 seconds. And that's not just true today, but other time Slack has been down as well.
"If it's black, it's confirmed delivered" is not an invariant.
Recently i've realized that this actually introduces more typos -- where a large number of phrases are duplicated or corrected typos reapplied.
There's something wrong with slacks operational transform or CRDT implementation or whatever they use to get edited messages to converge
I'm pretty sure they have none of that, considering you can only edit your own messages. So what's likely happening is that two quick edits are reaching the server at the same time and overriding each other.
I suppose it's possible that the corruption happens on the client side tho --
1. initiate edit action and get editable view of snapshot of text
2. server acks some previous edit request causing some client state related to the message to update and promote a previous edit in some way
3. hit save after finishing editing -- and some delta operation on the client side updates a different message state than the one i initiated edit action from ...
But that doesn't mean my observation of the behavior of the bug is unlikely.
And also -- there is not a hard requirement that only one editor exists -- the same user could use multiple devices at the same time. Consider that and you might find your assumptions to be invalid.
(Where a message sent doesn't match what was typed sometimes.)
I don't mean to disparage at all, but IPS monitors are far from universal.
The RGBA value for the "unsent" text is #1d1c1db3. Normal "sent" (or "attempting to send but haven't yet decided sending will fail" is #1d1c1d. The RGBA value (alpha = 0.7) ends up being equivalent to #616161 when rendered over white background which the Slack default skin does.
Demo for reference: https://jsfiddle.net/9smqe8y7/
Just... how!?