Phoenix LiveView is now... live!

phoenix
liveview
#8

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!

5 Likes

#9

Whooo hoo! Congrats Chris, José and everyone who worked on or helped contribute towards it :orange_heart:

Can’t wait to try it out now :003:

(Have also split these posts into a dedicated thread :023:)

3 Likes

#10

+1.

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

1 Like

#11

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 :smile:

1 Like

#12

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?

Boom
<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?

Rainbow

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 not saying that one is better than the other, but phoenix_live is definitely not leveraging full JavaScript potential to the webapp developer as I see it now. It’s about writing code in one language (Elixir) and keeping state on the server. Which can be nice.

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! :green_heart:

9 Likes

#13

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? :slight_smile:

  • 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 :slight_smile:

26 Likes

How do you achieve Optimistic UI in Phoenix with vanilla JavaScript and/or LiveView?
#14

:007: :007: :007: :007: :007:

That list covers pretty much everything I wanted to use it for …and more! :003:

5 Likes

#15

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!

8 Likes

#16

What I just thought to ask about, is already there. Thank you guys! (@josevalim, @chrismccord and other contributors)

2 Likes

#17

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

5 Likes

#18

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.

1 Like

#19

Just when you thought life couldn’t get better.

2 Likes

#20

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.

5 Likes

#21

Awesome great work @chrismccord, @josevalim and everybody else who is contributing! Thanks!

3 Likes

#22

Can you elaborate more on what you did?

1 Like

#23

Congratulations on the launch. I’ll hold my hands up as one of the people filling your inbox :sweat_smile:.

I’ve actually been working on an interactive form all week, and have been trying a few client side approaches (Svelte V3, React, Vue) and some server side ones (Drab, Channels hooked up to Stimulus). When I saw LiveView this morning I immediately downed tools and had a play to see what a LV implementation would look like.

The form that was live until earlier was powered by Drab, and along with rebuilding the form half a dozen different ways I felt pretty confident putting together the LiveView version. I have to say that it excels at ease of use and logical API. Quite similar to Drab.Live in this regard and also Phoenix Channels.

That said, I ultimately put LiveView aside and finished my Stimulus/Channels enhanced form. I couldn’t quite get my head around using it with forms and changesets. LV only operating on the form, and not the inputs confused me. For example, I couldn’t work out how to dynamically add a new record to an association without having a phx-click on a button inside the form. That didn’t play nicely with the phx-validate, and it became a case of either or, and I simply couldn’t replicate what I’ve built with Channels and JS.

I suspect that I’m missing something, and will take a proper look at LiveView next week, as your comment…

…makes me believe what I’m doing should be possible.

Anyway, congratulations on the launch! Even as someone who’s very comfortable with JS, I can see myself reaching for LiveView often!

4 Likes

#24

You can use Phoenix.PubSub (which Phoenix will use by default), if you don’t want to depend on Postgres. Regarding large collections, right now adding a new entry will always reload the whole page but we plan to include mechanisms were you only append/prepend items.

8 Likes

#25

Oh fantastic, thank you!

I’ll definitely take a look at this and it really is time for me to roll my sleeves up and get into Phoenix properly.

1 Like

#26

Just thought I’d try out the rainbow torture test and I’m really impressed. I managed 9 windows, all cranked up to 100FPS before I hit 100% CPU usage on a $5 Digital Ocean droplet. My (high spec) MacBook Pro was having more problems with it than the remote server was.

I think you’d have to have quite a lot of users (when using LiveView as intended) before you’d put some hurt on even a modest dedicated server. Thorughly impressed!

7 Likes

#28

I knew this was going to be a great weekend :partying_face:

2 Likes