Hacker News new | ask | show | jobs
by keymone 1876 days ago
From the tech talks I vaguely recall, LiveView folks seem to disregard latency, which is where the entire model falls apart for me because the moment you need more control on the client over what to do when the server is not responding - you’re entirely out of luck.

Though maybe I’m wrong and there has been some new developments to address this, I wasn’t following too closely.

3 comments

On the contrary, LiveView documentation acknowledges this and suggests to handle such scenarios using client side tools:

There are also use cases which are a bad fit for LiveView: Animations - animations, menus, and general UI events that do not need the server in the first place are a bad fit for LiveView. Those can be achieved without LiveView in multiple ways, such as with CSS and CSS transitions, using LiveView hooks, or even integrating with UI toolkits designed for this purpose, such as Bootstrap, Alpine.JS, and similar.

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#m...

Sorry, that’s not acknowledging that latency can become an issue, that’s acknowledging that using server-side rendering for things that don’t require a server isn’t the best of ideas (shocker, I know).
You would have latency in all apps that require a server round-trip regardless of the stack used.

When you need to go to the server, you go to the server. There's no other way around it.

I would be curious to hear how you solve this in other stacks? SPAs, whatever, when they need something from the server, they reach for the server.

imagine an SPA for a basic CRUD system. there's a list view and details view with a delete button that returns you to the list.

in liveview server renders me the list view, i click details, server renders me details view, i click delete button, server renders me the list view.

if there's big latency/connection error/etc between clicking delete and getting back the rendered list - user just has to wait.

in spa i could optimistically assume that delete worked and render the list that i already have cached without the deleted item, allowing user to continue working immediately and if there was a disconnect/error - i could retry that delete in the background without bothering user, only prompting them after some number of retries.

don't see how could i implement this workflow in liveview.

You can do that in LiveView just as easily. Remove the item client side, then pushEvent to the server to handle the deletion. In case of any errors, notify the user, refresh the state .etc

pushEvent, pushEventTo (from client to server) [0]

push_event (from server to client) [1]

[0] https://hexdocs.pm/phoenix_live_view/js-interop.html#client-...

[1] https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#p...

> Remove the item client side

so, "just use JS"?

> In case of any errors, notify the user, refresh the state .etc

so, "just use JS"?

every time you say "just use JS" you're diminishing the usecase of liveview because if i need so much js logic - why do i need to also use liveview if i can just use a framework/environment where i can share codebase between client and server seamlessly and have full control.

You could just delete the row with alpine or do a 3 line JS hook if you wanted to, it's quick and easy. That sounds a strange workflow though, it's generally better to make users wait for deletion.
isn't it funny that when you're trying to praise tech you like, all sorts of examples jump into mind, but when you try criticizing something you like - all that imagination vanishes and all existing examples can be dismissed as strange :)
What exactly are you thinking in terms of latency becoming an issue under LiveView but not on normal requests?

Do you mean when websites just need a full refresh because they lost their requests on some callback and no-one implemented recovery across the 5 levels of callbacks or something more specific?

Well with Liveview you go "full server state" for everything that you would normally just use plain JS for. For instance, toggling a checkbox or collapsing a div.

Having latency on such lowlevel interactions might make the UI feel sluggish as a whole.

Yeah certainly, but I'm not sure people are using it that way?

Most examples are to show cool stuff you can do, they're not production vetted. Like most JS examples out there don't really mean that people should be publishing live credentials with their bundles.

I imagine in most cases one would leave everything that is not behind a logged in status as normal routes/pages (signin, landing, contacts, etc). Or if not that those would be things requiring a socket/real-time interface anyway.

For the interactions, I don't think you even need to use alpine.js. Plain setup on DOMContentLoad, CSS Dropdowns/collapsibles that are replaced on JS load, proxying LiveView DOM/Morphdom events (if needed) so other components (even vue,react, etc) can listen to them, and CSS animations.

  import { setup_live } from "./phx/setup_live.js";
  import { setup_dropdowns } from "./interactivity/dropdowns.js";
  import { setup_collapsibles } from "./interactivity/collapsibles.js";
  import { setup_links } from "./interactivity/links.js";
  import { setup_inputs } from "./interactivity/inputs.js";

  function setup() {
      setup_live();
      setup_links();
      setup_dropdowns();
      setup_collapsibles();
      setup_inputs();
  }

  document.addEventListener("DOMContentLoaded", setup);


I went as far as having `onclick` handles and global window functions. Complete heresy. Yes, it's not 100% JS free, but it's pretty much low overhead.

Then LiveView is mostly for your admin dashboards and logged in users views, where it makes it pretty easy to do real-time feedback type of interactions/views and spa like navigation. Since you have proper auth and identification on the user, you can just log them off, rate-limit, block an account, and close their socket if needed.

Have you figured out any good way to have per-page javascript where the JavaScript is only sent over the wire for that pages?
You don't have to. You can totally use JS for these in Liveview
Possibly many LiveView tech demos / projects by the community haven't had much thought into latency, but LiveView itself even contains a latency simulator[0] built-in. Additionally, it can toggle classes on elements when you click them and turn them off again when an acknowledgment has been received from the backend [1]. Finally you have the JS hooks, through which you can just implement any kind of loading indication you want on the frontend. So the tools are there, they just need to be used.

[0] https://hexdocs.pm/phoenix_live_view/js-interop.html#simulat...

[1] https://hexdocs.pm/phoenix_live_view/js-interop.html#loading...

One trick I remember using (~two years ago, so early LV) when handling click events was to put everything async/not needed to reply in a spawn() function.

But yes as soon as you're on the internet you'll often feel the delay if your app is interactive.

The problem is that it's a bit random, because the network and the VM performances are never totally linear.

I remember implementing a countdown (using 1s send_after()) that would work fine most of the time, but sometimes there would be some hiccup and the countdown would stall just a bit and then process the counter in an accelerated fashion, which was terrible from a UI point of view, so in the end I did it in JS except for the update once the end reached.