zwippie

zwippie

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
Post #11
chrismccord

chrismccord

Creator of Phoenix

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
Post #12
AstonJ

AstonJ

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

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

5
Post #13
hectorsq

hectorsq

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
Post #14
DevotionGeo

DevotionGeo

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

2
Post #15
mythicalprogrammer

mythicalprogrammer

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
Post #16
simon

simon

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
Post #17
runexec

runexec

Just when you thought life couldn’t get better.

3
Post #18
montag

montag

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
Post #19
sandergroen

sandergroen

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

3
Post #20