How do you achieve Optimistic UI in Phoenix with vanilla JavaScript and/or 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).

-> rest of the process of sending message to the server, saving to database, OK response from server everything was done in the background.

or vanilla JavaScript

Sounds like something that can be accomplished with Web Workers.

Can I use … Web Workers

1 Like

thank you for the response!,
I’ll read about web-workers to find out if it will work for me or not. I don’t wanna use React or Vue for otherwise very simple project.

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.
hithere
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).

3 Likes

Sending a single message isn’t very hard to do in Optimistic UI way, but sending multiple messages, and dealing with their order might be harder. A message sent later and being smaller may reach earlier (especially when user’s internet connection is too slow).
One solution coming to my mind is, update the UI, add message to some state container or session/local storage, send message to the server, update session/local storage about any message not delivered, have some mechanism to update the UI.
Reef is a lightweight helper function for creating reactive, state-based components and UI, and doesn’t have a virtual DOM, so it might be a good fit for your project.

Of course it will take a lot of work, and it won’t be as easy as doing it using Apollo with Graphql, because the creators of Apollo are actually those who created Meteor too, and they have a good track record of creating Optimistic UIs and they were the ones coining the term Latency Compensation.

2 Likes

Reef is an anti-framework.

I think he is encouraging people to peek under the hood rather than just simply use it.

Daily Developer Tips:

Bonus: Lean Web

5 Likes

A bit of a tangent and just my 2cents, but any lib/framework that I would enjoy using would have that as an extension to the core functionality. There’s a ton of complexity I’d rather be able to hook into and write my own optimistic UI (I’ll shorten this to O-UI) elements into my software rather than have that baked in and either scare me with all the behind-the-scenes magic and/or make the base application much more complex than I’d want initially.

For example with chat messages, if O-UI messages fail, how would I handle the UI rollback? Does that mean with meteor I’d have to write logic for how to handle that failure just for my first iteration on that feature? With a more basic request/response I could simply have an error message show up in some box that would take every bit of 15 minutes to code up. With O-UI I think I’d need at lot of UI logic around all of the possible transitions at all states in order to not confuse the user.

You are not wrong - but UX focuses on “what works best for users”, not on making the developer’s life easier or paving the road to an MVP.

The Elements of User Experience (2010)

p.82:

p. 114:

3 Likes

I don’t think you can consider “what works for the user” in isolation of being able to get a solution out quickly to the users that works “well enough”. A problem solved sub-optimally, quickly and with continuous improvements will almost always (maybe just always?) be a better solution. The more quickly you can provide your solution, the more quickly your users can show you their true intentions for the “final” product allowing you to arrive at the most optimal product more efficiently.

I do believe O-UI is an important component to giving your users confidence in your software, but introducing complexity early on could have you solving a problem your users didn’t need a solution for and then you might find out too late that you were spending resources on the wrong solution all along.

Contrast that with an iterative approach where the users problems are solved more quickly and they continue to experience the joy of seeing improvement features focused towards the problems they care about rather than potentially spending a lot of resources on some feature they never needed to begin with.

I do think we agree with each other, but I think MVPs are a very important part of getting the UX right. If you don’t have a good way to understand your users, you’ll never be able to make exactly what they want.

1 Like

My intention wasn’t disagreement - I was just pointing out that there are different perspectives and mindsets. Developers, managers, and whoever pays the bills have to be concerned with the economics of the product. Users on the other hand really don’t care, they are primarily concerned with whether or not the software is getting in their way - and the UX area is primarily about them.

Developers (should) tend towards “making invalid impossible” but users don’t like to be blocked (even if we think it’s a reasonable concession). In some ways this reminds me of Your Coffee Shop Doesn’t Use Two-Phase Commit - the real world favours the happy path but when things go south it simply is time to issue a compensating action.

3 Likes

4 Likes

thank you!

I’m looking for kinda the same thing that is a client library (named and/or plain vanilla js) that works well with PhoenixLiveView. What I’ve experimented with so far are Elm, Svelte and Vue.

It turns out virtual dom or no virtual dom doesn’t matter; they don’t work well as integration. I have used phx-ignore which is great, the 3rd party widgets don’t get patched and we can put phx-* events inside them to do things on server. However, having multiple compilers or engines controlling the same container is an anti-pattern (shared mutable state).

The ideal js lib should be able to embed inside live view AND have live view embeds inside their containers (note that I say live view instead of morphdom because we consider as a whole). Tbh, those jQuery plugins was working ok together.

Ok, real question is; is there a ui lib that works with LiveView very nicely? I haven’t tested Stimulusjs but it seems to integrate well …

1 Like

any updates on this?
Can we now achieve Optimistic Ui updates with Phoenix liveView?

I thought optimistic UI updates were frontend related, not backend…

It means You don’t wait the server response to update UI, but if the server response fails, it can be rolled back.

Given that liveview is server related, I don’t see how this could be working. (Without help of JS)

2 Likes