Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think Phoenix Live View is maybe the most compelling story around this (https://github.com/phoenixframework/phoenix_live_view). I'm moving a side-project from React/SPA to Phoenix live view and it's kind of amazing to get the dev ergonomics of a server-rendered page with the UX benefits of a SPA.

This course is a pretty great intro: https://pragmaticstudio.com/phoenix-liveview



I've been playing with LiveView myself for personal projects and it is very nice.

One interesting thing is that it makes you consider memory issues again since all your rendered data structures are held in memory in the LiveView process unless they are explicitly cleared after the render with "temporary_assigns". For apps that would have to hold and transfer a lot of data up and down the channel I've ended up using a hybrid of LiveView with divs set to phx-update="ignore" in which I mount React components.


I'd say that's the main (potential) 'problem' with LiveView, alongside latency issues.

In practice, I've usually found that the advantages outweigh the disadvantages when it comes to the former. Beefing up my servers seems like a worthwhile trade-off.

When it comes to latency, or related issues, I find that I'm still so much better off using LV as a basis and 'dropping down' into plain JS or (p)react when I need it.

We recently delivered a project that involved a whole bunch of stuff that LV was a perfect solution for, but also a core bit of functionality that required various kinds of animations. We ended up using LV wherever we could, and piggy-backed on the LV channel (websockets) to handle synchronizing the animation stuff. The actual code to animate things was just plain old JS. Worked like a charm!


I'm still using LiveView in a lot of the other parts of the app - places like signup/signin where the having the form validation seamlessly done server side using changsets is very, very nice. I'm also using in places where I would normally have to expose an api endpoint for CRUD and instead I'm using events and handling it in the LiveView. Again, very nice.


Agree completely. My only concern is that so many imitations are attempting to pop up in other languages and you just can’t do it as effectively.

There are so many tradeoffs present that happen to result in the necessary set of functionality to do this efficiently that aren’t easily present outside of the BEAM.


What about this can't be done with async/await?


Everything can be done in everything else. The only question is how well it fits, how contorted does it have to be, what comes naturally.

With BEAM, robustness is a special feature. In the BEAM you can kill, restart and replace processes all over the place and everything stays working pretty well, because its structure means everything written for it is designed with that in mind.

In a typical async/await server side application sharing state across clients, killing, restarting and replacing usually means the whole single process containing all the async/await coroutines, and the fancy per-client state you were maintaining is lost.

You can of course serialise state, as well as coordinating it among multiple processes, but that takes more effort than just using async/await in a web app, and often people don't bother. Doing that right can get tricky and it requires more testing for something that doesn't happen often compared with normal requests. So instead, they let the occasional client session see a glitch or need reloading, and deem that no big deal.


It can be done, but you’ll see a lot of weak points. It’s probably worth a blog post to explain it. There are several layers in the language that combine to make this work.

At a high level, is the combination of process isolation, memory isolation, template delivery, websocket capability and resilience on top of all the standard web bits.

It will be really difficult to pull off with a good developer experience and minus several deficiencies outside of the BEAM. Anything’s possible though.



It's still not a silver bullet. There's lots of things in a LV driven app where you're still wondering what front-end library to use with it.

Typically you wouldn't use LV to handle:

Menu dropdowns, tooltips, popovers, modals (in some cases), tabs (when you don't want to load the content from the server) or things that change the client side state of something but don't adjust server state. That could be things like a "select all" checkbox toggle where that doesn't do anything on its own other than select or de-select client side check boxes or toggling the visibility of something. There's also things like wanting to copy to the clipboard or initiating stuff to happen on drag / drop (like animations).

Basically you'll still find yourself wanting to use JS with LV. Whether that's Stimulus, Alpine, Vue, jQuery, vanilla JS or something else that's up to you. But I do find most of the above necessary in a lot of web apps I develop.


> It's still not a silver bullet. There's lots of things in a LV driven app where you're still wondering what front-end library to use with it.

> Typically you wouldn't use LV to handle:

> Menu drop dropdowns, tooltips, popovers, modals (in some cases), tabs (when you don't want to load the content from the server) or things that change the client side state of something but don't adjust server state.

My experience is that LiveView is fine for all but the last use case. And while in practice I often don't really need to keep things client-side-only, when I do it's often pretty easy to just write a bit of js and, if necessary, use hooks and events to communicate with the surrounding LiveView(s).

In fact, I vaguely recall that in the early days of LV, the creator himself argued that it should be used for just 'smaller interactive stuff'. Over time, we all discovered that LV does surprisingly well for SPA-type use cases (and as a result we now have stuff like router-level LiveViews (that take over the whole page), live_redirects, url updating, and so on).

> That could be things like a "select all" checkbox toggle where that doesn't do anything on its own other than select or de-select client side check boxes.

Why wouldn't you just keep that within the server-side state LV paradigm? I've done just that in a project I'm working on.

> There's also things like wanting to copy to the clipboard or initiating stuff to happen on drag / drop (like animations).

For those things you write js, yes.

> Basically you'll still find yourself wanting to use JS with LV. Whether that's Stimulus, Alpine, jQuery, vanilla JS or something else that's up to you. But I do find most of the above necessary in a lot of web apps I develop.

Absolutely, but I'm continuously surprised how little of it I need, and how often I /think/ I do just because I haven't quite wrapped my head around the different paradigm.


> My experience is that LiveView is fine for all but the last use case.

I wouldn't want to impose a 50-500ms+ delay on someone to show a menu drop down or a tooltip or most of the other things listed out.

With LV everything involves a server round trip. That's great for when you need to make a round trip no matter what (which is often the case, such as updating your database based on a user interaction), but it creates for very unnaturally sluggish feeling UIs when you use LV for things that you expect to be instant.

Even a 100ms delay on a menu feels off and with a good internet connection if you have a server in NY, you'll get 80-100ms ping times to the west coast of the US or the west coast of Europe.

LV feels amazing on localhost but the internet is global. I still think it's worth minimizing round trips to the server when you can, not because Phoenix and LV can't handle it but because I want my users to have a good experience using the sites I develop.


> My experience is that LiveView is fine for all but the last use case. >> I wouldn't want to impose a 50-500ms+ delay on someone to show a menu drop down or a tooltip or most of the other things listed out.

It's basically a UX standard that a tooltip only shows up after a few seconds, so that strikes me as a particularly bad example. That said, sure, if instant tooltips are important, a tiny bit of js and a specific class name in your markup would solve it.

> With LV everything involves a server round trip. That's great for when you need to make a round trip no matter what (which is often the case, such as updating your database based on a user interaction), but it creates for very unnaturally sluggish feeling UIs when you use LV for things that you expect to be instant.

Yeah, I do agree on that. While I feel using a tooltip is a bad example, in practice I wouldn't implement tooltips or menus in LiveView. Those would just be solved via some CSS trick or some plain old JavaScript.

> LV feels amazing on localhost but the internet is global. I still think it's worth minimizing round trips to the server when you can, not because Phoenix and LV can't handle it but because I want my users to have a good experience using the sites I develop.

I'll give you that generally I wouldn't use LV for tooltips and popups. But in part because those are really easy to solve without it.

But for /so/ much of the stuff involved in a SPA the latency has not been a problem in practice.

Consider tabbed content. Sure, I could make it all 'instant' by preloading the various bits of content and writing js to switch between these bits. But I can avoid that entirely by preloading those bits in my templates and using LV to switch/update classes. The tiny latency downside is worth the upsides: being able to update the content in those tabs live with no extra code (no API calls, no client-side frameworks, and server-side rendered as a nice bonus!).

My general approach is that I use LV as a default, and then use the 'Hook' system and some custom JS when latency is a concern. In practice that doesn't amount to much. So it's not a silver bullet, but it simplifies so much of what a typical SPA does.


If you preload, where does LV introduce latency in that tab example?


The click would be sent as an event to the server, where the state is changed (setting "active_tab" or something like that). Then the view would be re-rendered (probably only changing a few class names) and the diff sent back down to the client.


Gosh, that feels so inefficient (as a js dev here). Then again... React had it's naysayers for sometime because 1. JSX, 2. nobody saw dom diffing as truly fast enough. But dom diffing is absolutely faster than asking the server to update a classname.


True, in this particular case it does seem inefficient. And of course there's nothing stopping one from just doing this with a bit of js.

But in the bigger picture, the advantages of this approach are huge:

1. no need to maintain state, routing, and so on on the front- and backend, which removes a huge source of complexity. It's all in one place. And if something in the DB is updated, it's trivial to make it live-update the client state. And because of websockets, such an update is almost instant.

2. being able to use the same language (and templating) on server and client (for the most part).

3. the ability to just use regular function calls to retrieve data, and selectively display what you want by using it in templates. No need to set up endpoints for the client, and no need to worry that perhaps accidentally the endpoint might send data down the wire that shouldn't be there (and that you might not notice because the JSX doesn't display it). I think in just the past year I've read about a number of serious data leaks that were basically a result of this.

4. no need (or not as much need) to keep an eye on the js payload. Want to format dates in particular way? Just add the dependency and use it however you like. It's only diff in the output that gets sent to the client!

5. little to no need to deal with a complicated build process.

6. server-side rendering out of the box, and in a simple manner!

7. less taxing on the client. No need for processing templates and a lot of code. Of course, the downside is that the server has to do more work.

Now obviously latency can be a downside, as is (potentially) increased memory and processor usage on the server. It's not a magic solution to everything :). Hell, my last project still needed quite a bit of javascript for some heavy interactivity where latency had to be avoided. But it's still astounding to me how many projects have become drastically simpler with the LiveView-approach!


We’ve gone all in and are using it a lot in production. There is one big trade off to consider though: point of presence and global availability. We’re ok, as we’re a UK based website and hosted in GCP europe-west2, but we had devs in NZ for a while, and they said that, understandably, the site was really slow for them due to the latency. Beam has the ability to link instances and have them cluster, so you could do something like that across multiple regions globally, but there is a trade off to consider if you run a global service: you’re trading an over engineering and sync problem, for a potential distributed systems problem if you try and make the same liveview site available performantly in multiple global regions.


as a user, this is the kind of experience I want on the web. any spa like page should always degrade back to web standards. and it should be lightening fast. and not spin my cpu fan or warm my desk.


Yes, and please no more load screens for a page of text a few photos, (looking at you Blogger), just send the text and links to the photos.


Blazor Server (https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor) is similar. It's a very productive environment.


Can't believe this didn't get mentioned in the article.


I started this course and the animations/presentation are amazing. some really clear explanations. But the fake cute-sy dialogue and the extra fluff that says how wonderful and amazing and great and FUN liveview is means I didn't get past the first video


I liked their Tetris videos, which I watched the first several of.

That said, if you want a different approach then check out my series at https://alchemist.camp/tagged/Reactor

I covered the whole process of building the site for my podcast https://reactor.am in the series.

Note that LiveView still isn't at v1.0 and breaking updates have been common. You'll have a much better with my LV tutorial or anyone else's if you use the exact same library versions we do and upgrade at the same point the tutorial does.


Having deployed liveview for an admin dashboard, I gotta say, it really is great FUN, and no-fuss, even if you're slinging together a system that customers never see so you don't care if the code gets a bit knotty, and your datastructures are abjectly awful.


What is Live View not good at?


It's not suitable for using the client's computer to mine crypto currencies, doing graphics processing on the client, doing numerical processing on the client or doing anything purely on the client without server interaction.

For things where you generally need a trip to the server anyway, like validations, it's great.


Yup, exactly. If you’re mostly building a client application (or a p2p client-server application!) but it happens to live on the web platform, PLV does not seem like a great fit...at least not this year. Honestly BEAM seems great it ought to be great for that generally!

Maybe if you ran the server portion of PLV in the browser...but then you’re just back at React anyway I suppose.


You wouldn't use it for an offline app, but that's not what it's being marketed towards.


Is this similar to Vaadin?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: