pillaiindu

pillaiindu

How do you achieve Optimistic UI in Phoenix with LiveView?

Elixir is fast, but not everyone on the planet is having a fast internet connection. Optimistic UI (previously called Latency Compensation) is a concept first introduced by Meteor framework.

Let me explain what Optimistic UI / Latency Compensation is:

For example you’re sending a message through a chatbox.
In traditional way:

  1. You typed the message
  2. pressed enter or clicked send button
  3. the browser sent an ajax request
  4. the data was stored in the database at server
  5. the server sent an OK response
  6. the message got copied from the textarea to the messages list
  7. the textarea got cleared.

In Optimistic UI way:

  1. You typed a message
  2. You pressed enter / clicked send button
  3. Message got copied directly to the message list, and the text area got cleared
    → rest of the process of sending message to the server, saving to database, OK response from server everything was done in the background.

So the Latency Compensation / Optimistic UI way feels a lot faster to the user, and it makes the UI bearable if the internet is slow.

(for details on Latency Compensation / Optimistic UI, read the linked post).

I asked Meteor team, if this feature can be used outside Meteor? They replied that Apollo client (for Graphql) which is created by the same team provides that feature under the name Optimistic UI.

I wanted to know if it’s possible using LiveView or vanilla JavaScript with Phoenix, instead of going the Apollo and Graphql way (which also brings the cruft of front-end frameworks like Vue and React etc).

Most Liked

josevalim

josevalim

Creator of Elixir

LiveView now adds some classes, such as phx-click-loading, whenever you do an action. This can be used to provide some UI feedback and in many cases. For more complex cases like the chat example, then you need to fallback to JS with phx hooks.

peerreynders

peerreynders

True Lies Of Optimistic User Interfaces (2016-11-15)

In most cases Web Worker is likely overkill for this as the server interaction is asynchronous to begin with. You are simply updating the page before the request to the server is made. So working with Promises or async functions should be enough.

What can make this approach more complicated is that you need enough context to undo/update the page should the request fail, especially as the user may have taken other actions since then.

I think one good example of Optimistic UI are iMessage messages.


The text bubble appears as soon as send is activated - even though sending hasn’t completed. Later, if the the message can’t be delivered it is marked as such (and the device vibrates to call attention to that fact).

Last Post!

D4no0

D4no0

While I generally agree with this, I also think that a lot of things we take as standards these days, like for example that UI should be always responsive in some manner just don’t make much sense for some projects.

I used liveview for admin panels for almost all of my projects. There, I don’t care about user latency, even though that can be a problem sometimes if you have huge payloads (which happens more often than I expected at first). You want a fully reliable system that is fully synchronized with what actually happens on the server, and the complexity running a configuration server is usually insane, so adding the additional layer of client-side state is just unwise in such situations.

We have to fully understand where it makes sense to add additional features, otherwise I think the trip to server liveview offers by default is superior to any hacks involving client-side state modifications.

Where Next?

Popular in Questions Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement