Phoenix Live View is now publicly available on GitHub.
Here’s Chris McCord’s tweet announcing making it public.
Phoenix Live View is now publicly available on GitHub.
Here’s Chris McCord’s tweet announcing making it public.
So… my weekend plans just changed
It looks amazing! But is just me or this workflow of sync client data with server one can take a lot of network bandwidth?
On a SPA or Server Render you normally don’t tranfer so often
For an “image editor”, yes, absolutely would use more bandwidth than a client app, but that example is more to showoff the minimal diffs we apply on both client and server. The autocomplete search example is a much better real-world comparison when discussing bandwidth:
In this case, the LiveView diffs match the best, most optimized server JSON you could write by hand, and you get that for free with zero effort. For some use cases we will use more bandwidth , like real-time form validations, but there are others where we can match, or potentially beat, a SPA bandwidth wise.
To add to what Chris said, there is also a feature to add debouncing/throttling in the cases you don’t want to immediately send changes all the time to the server.
Oh I see makes sense then, In your opinion what are the best use cases for LiveView? Do you think something like a social network could fit into it?
That’s what I love about Elixir community in general! You think about everything when giving us new tools/features, thank you for the amazing work guys!
Whooo hoo! Congrats Chris, José and everyone who worked on or helped contribute towards it
Can’t wait to try it out now
(Have also split these posts into a dedicated thread )
I’m really, really keen to start playing with this and finally seeing if I could replace Meteor with it for the application I want to update (and now migrate).
Can’t wait to try this out!
Big "thank you"s to everyone involved in that project, now lets all take this baby for a test drive and give feedback, so they can continue their work
Cool stuff! Thank you all for your hard work on this project and so much more.
Here are my impressions and thoughts after two hours of fiddling with the library and demo project and (mainly) thinking about its use cases. I think it’s impressive but also have some questions and observations. I assume that you are looking for feedback, so here it goes.
User CRUD example
The way the user CRUD templates in the demo almost looks like they could have been copy/pasted from the regular HTML version is very nice. The differences are most about routing and form options. Leaves you wondering what agnostic code exactly could eventually replace
Routes.live_path(@socket, UserLive.Edit, user) and
Routes.user_path(@conn, :edit, user)? But you chose to give these templates another file extension to keep them out of the eex compile step I guess? The (inevitable) coupling between phoenix_html_form and phoenix_live is very visible here. This could be a strength if you can keep them working together.
Image Editor/Autocomplete Form
Throttling and debouncing of client side events is so obvious that it should be built-in, good to hear that you are working on that, perhaps with something like
<form phx-change="suggest" phx-submit="debounce(search, 200)"> in the search with autocomplete demo. But my guess it that you’re heading for a more declarative approach like
<input type="range" min="10" max="630" name="width" value="<%= @width %>" phx-debounce="200" />. I noticed that the
phx-submit-every should already work for form submits, but not for value changes within a view.
How configurable or extensible are these attributes/behaviours?
<img phx-click="boom"> started me searching where
boom was defined, but of course it was just the name for an unkown event that made the server crash and recover to an empty form. It made me wonder what state you want to present to the user when things go wrong on the server. It would need a hellofalotta bookkeeping on the server side to mimic exactly what all those connected browsers keep as their own last known state. A full page reload is just too harsh, so creating a full SPA is probably out of the picture for phoenix_live?
Performancewise, the Rainbow demo did not convince me, sorry. With the browser devtools open it crashed my Chrome tab hard, but that’s understandable. With devtools closed it worked fine in the browser but gave me a 10%+ server cpu load (on an ubuntu vm with lots of headroom). So, while I get that this example is a bit of an extremity, it was definitely not a super showcase for connecting many concurrent users with up-beat computational requirements.
Where to now?
I can see that phoenix_live has a lot of potential, but what can become it’s real strengths?
Can you offer developers more than magic to socketify a CRUD resource, or is that what you are aiming for? Because (in this first/short review) I don’t see a lot of possibilities for quick extensions or escape hatches when it comes to fine-tuning client-side behaviour. Of course that can be a good thing, a goal, I don’t know. It’s definitely a certain state of mind when dealing with HTML forms and views. There have been many previous endeavours to ajaxify forms and views in all shapes and languages, I’m sure there is a lot to learn from that while socketifying.
So before everybody dives in and tries to rewrite their Meteor application into something phoenix_live (sorry @simon), think about how completely different the two are.
I’m really sorry if this sounded all too harsh because I enjoy thinking about this kind of stuff and I love the Phoenix framework. Let this late-hour rambling of mine drive you to higher heights!
Thanks for the feedback!
There won’t be anything to configure debouncing wise, as it will only be annotating the DOM like you mentioned –
phx-debounce="1000" or similar. Our greater JS interop story is still TBD. Today your only option is to wire up event handlers directly like
onclick="myFunc(event"). There’s a lot explore here, but I’m intentionally punting on this for now until usecases help present a generalized solution.
The only purpose of this contrived example is to show the server can handle re-rendering and sending diffs such that 60fps animations are possible. It’s not a real usecase, but it’s a fun example to showcase our general performance. I disagree about not being a good showcase for many users causing many renders ¯_(ツ)_/¯
the “boom” is arbitrary. It could also be “this-will-explore” since it will cause a function clause error and intentional crash on the server. The purpose there was me testing the failure and recovery modes of parent/children/etc.
State wise, the same rules apply on the live view process as any other elixir process. The live view recovers to a known good state, which is an empty form in this example. For durable server specific state, you’d handle it the same way you handle it in Elixir today, which is to say it’s up to you to store outside the process as needed. This may sound like a hand-wavy answer, but I’ll repeat it’s the same story that we have in elixir processes today and restarting to a known good state is one of the things we want in recovery. For client specific state, we do have the live view session, and we will expose primitives that allow you to update the session with state programmatically. So things like
last_seen_id for a chat app, or in your example, specific user inputs could be ‘persisted’ in the live view session and recovered on crash.
As I’ve mentioned in my talks, our goals are to start small and see where we programming model breaks down. I think we can go farther than a lot of people think. Strength wise as it exists today, I can confidently say LiveView will be great for:
bits of required rich interaction in your app. Think notifications, async job statuses, progress bars, dashboards, widgets, etc
interactive forms. Think ‘client-side’ validations, dynamic forms that update inputs/options based on selections, must-step wizards, etc
any realtime updates you wish to push out to users or have users’ page info update based on things happening in the system. I’m going to flip your comment back at you:
more than *magic to socketify a CRUD resource*
think of how many pages our web applications render where otherwise static data could be live if the cost to support it was sufficiently low. Today that cost is too high for most tooling without buying into a ton of complexity, even for pages that are ultimately dumb “CRUD” data. LiveView makes it trivial to enhance these “CRUD” pages with realtime updates that deliver instant UX increases, so don’t be too quick to discount this side of things, after all how many of us are building glorified spreadsheets, SPA or not?
any rich interaction where the server is required to be there. Think autocomplete and search results – things that are impossible or impractical to cache on the client and don’t make sense in any optimistic UI context. (google can’t cache their search index in an SPA for example)
So to close, we know the areas LiveView isn’t a good fit – highly latent clients, usecases where optimistic UI is required, desktop-like interfaces, offline support. What specific usecases we venture into in this brave new world… we’ll find out together
That list covers pretty much everything I wanted to use it for …and more!
I only want to thank you for LiveView. It is a gift for people like me that are tired of developing SPAs.
Thank you Chris! Receive a big hug!
This is exactly what I thought when I saw the demo. It’s great. I don’t want to do full blown SPA. Often time then not I just want a web app, SPA application for me is rare. The few I think are best cases are admin tools, gmail, word doc online, etc… Most of the time I want a web app that is SEO friendly so I can bring in traffic to authoritative website.
It’s a perfect use case for a full stack like myself that don’t have time to go deep in every aspect of front end (even though I did VueJS).
Thanks @zwippie, that was all good stuff and @chrismccord’s reply helped me realise that I probably need to stop saying that I’m hoping that I can replace a Meteor application with a Phoenix and LiveView one because I think that a lot of the heavy lifting can be done using channels and Postgres’s Listen/Notify commands (but this is something I need to verify).
LiveView interests me from the angle of interactive forms, giving feedback from async tasks (one example is that we use Google’s geocoding APIs to fetch addresses from coordinates so showing a progress indicator and then the results would be handy), etc.
Where I’m currently unclear is whether updating lists of data being shown to the user when database changes occur is best done via the aforementioned channels and Postgres’s Listen/Notify or whether LiveView will do that more simply too. I need to find some time to have a proper play with it all now.
Just when you thought life couldn’t get better.
Probably blasphemy but I tested out using the Live View demo app with a custom vuejs based webcomponent (as a widget, not an spa) and it worked well.