News for hackers. Stuff that matters.
Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @03:42PM (#28620849)
Creator of Phoenix here. I'm happy to answer any questions folks have about LiveView, Phoenix, or Elixir in general. We've had some big LiveView features land recently with uploads and HEEx so now's a great time to jump in!
Re:How we got to LiveView by sgrytoyr on Wednesday September 22, 2021 @04:38PM (#28621459)
Almost every time I see a discussion about LiveView there’s someone complaining about the issue of latency/lag, and how it makes LiveView unsuitable for real-world applications.

From what I understand, the issue is that every event that happens on the client (say, a click) has to make a roundtrip to the server before the UI can be updated. If latency is high, this can make for a poor user experience, the argument goes.

As the creator of LiveView, what’s your take on this? Is it a real and difficult-to-solve issue, or do people just not see "the LiveView way" of solving it?

I think LiveView looks amazing, but this possible issue (in addition to chronic lack of time) has made me a little unsure of whether it’s ready to use for a real project.

Thanks for creating Phoenix, btw!

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @05:11PM (#28621870)
These kinds of discussions miss a ton of nuance unfortunately (as most tech discussions do), so hopefully I can help answer this broadly:

First off, it's important to call out how LiveView's docs recommend folks keep interactions purely client side for purely client side interactions: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#m...

> 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

Second, it's important to call out how LiveView will beat client-side apps that necessarily needs to talk to the server to perform writes or reads because we already have the connection established and there's less overhead on the other side since we don't need to fetch the world, and we send less data as the result of the interaction. If you click "post tweet", wether it's LiveView or React, you're talking to the server so there's no more or less suitability there compared to an SPA.

I had a big writeup about these points on the DockYard blog for those interested in this kind of thing along with LiveViews optimistic UI features:

https://dockyard.com/blog/2020/12/21/optimizing-user-experie...

Re:How we got to LiveView by sgrytoyr on Wednesday September 22, 2021 @06:15PM (#28622700)
Thanks for the pointers and insights. I’ve been reading up on this tonight (local time), and this whole issue seems to be mostly a misconception.

Between things like phx-disable-with and phx-*-loading, and the ability to add any client-side logic using JS, there doesn’t really seem to be any limitations compared to a more traditional SPA using (for example) React and a JSON API.

I hope I haven’t added to the confusion about this by bringing it up, I was just very curious to hear your thoughts on it.

Re:How we got to LiveView by Aeolun on Wednesday September 22, 2021 @07:50PM (#28623535)
I think the big difference is that with React a lot of interactions can be completed completely client side, with the server side component happening only after the fact (asynchronously).

I’ll grant you that that isn’t often the case, and recovering from inconsistencies is pretty painful, but I can see how people would go for that.

I kind of like the idea I can just build all my code in one place instead of completely separate front and back-end though.

Re:How we got to LiveView by omegalulw on Thursday September 23, 2021 @04:09AM (#28626492)
> LiveView will beat client-side apps that necessarily needs to talk to the server to perform writes or reads because we already have the connection established and there's less overhead

Don't modern browsers already share a TCP connection for multiple queries implicitly?

Re:How we got to LiveView by collinmanderson on Thursday September 23, 2021 @07:45PM (#28637009)
Yeah. The overhead I see that's being reduced from a performance point of view is the server not needing to query the session/user information on every message, compared to ajax. That's true for websockets in general. And then the responses might be slightly smaller because it is an efficient diff with just the changed information.
Re:How we got to LiveView by mrkurt on Wednesday September 22, 2021 @04:53PM (#28621646)
There's a funny story here. We created Fly.io, Chris created Phoenix. We met earlier this year and realized we'd accidentally built complimentary tools. The pithy answer is now "just deploy LiveView apps close to users". If a message round trip (over a pre-established websocket) takes <50ms it seems instantaneous.

This means moving logic to client side JS becomes an optimization, rather than a requirement. You can naively build LiveView and send stuff you shouldn't to the server, then optimize that away by writing javascript as your app matures.

What I've found is that I don't get to the optimize with JS step very often. But I know it's there if I need it.

Re:How we got to LiveView by raihansaputra on Thursday September 23, 2021 @01:04AM (#28625358)
How would you exactly 'optimize with JS'? Do you think this optimization can be done to the extent of enabling offline experiences? Might not be full functionality, but bookmarks/saved articles, for example.
Re:How we got to LiveView by sodapopcan on Wednesday September 22, 2021 @06:08PM (#28622625)
Lots of answers here including one from Chris McCord himself, but I'll offer my take based on my professional experience developing web apps (though I've never used Phoenix professionally):

A large majority of businesses out there start off targeting one region/area/country. The latency from LiveView in this scenario is imperceptible (it's microseconds). If these businesses are so lucky as to expand internationally, they are going to want to deploy instances of their apps closer to their users regardless of wether or not they are using LiveView.

LiveView could be a huge help to these startups. The development speed to get a concurrent, SPA-style app up and running is unparalleled, and it scales really well. My guess would that be that people who are worried about the latency here (which is going to exist from any SPA anyway) are the ones who are developing personal pages, blogs, educational material, etc. that they are hoping the world is going to see out of the gates. In this case, LiveView is not the answer!!! And as I've stated elsewhere 'round here, LiveView does not claim to be "one-size-fits-all". If latency really IS that big of a concern, LiveView is not the right choice for your app. But there really is a huge set of businesses that could really benefit from using it, either because they are a start-up focused on a single area/region/country, or they are already making tons of money can easily afford to "just deploy closer to their users" and could benefit from LiveView's (and Phoenix's) extreme simplicity.

Re:How we got to LiveView by louissm_it on Wednesday September 22, 2021 @06:24PM (#28622792)
Pretty much this. Also, I’m not sure most people realise how incremental LiveView can be. You can use it for a little widget on any page and later swap in a react component if you truly need one (which most apps probably don’t).

It’s not designed to run the NY Times. But it is a super useful tool that will benefit a ton of apps out there.

Re:How we got to LiveView by joppy on Wednesday September 22, 2021 @06:14PM (#28622690)
Is microseconds correct? Even with a good connection in online games I’ve only seen ping latencies of 3ms or so, and a more common range on an average connection is 20ms-50ms.
Re:How we got to LiveView by sodapopcan on Wednesday September 22, 2021 @06:32PM (#28622871)
Should be, though milage may vary, of course. I'm having trouble finding a better example but https://elixir-console-wye.herokuapp.com/ is made in LiveView. You can try it out and see what you get (I have no idea where it's deployed, it's a phoenixphrenzy.com winner and plenty more there to browse through). Its payloads are a bit larger than some typical responses I have in my personal apps and I'm seeing 1-2ms responses in Toronto, Canada (chrome devtools doesn't show greater precision than 0.001 for websocket requests).
Re:How we got to LiveView by coryrc on Wednesday September 22, 2021 @09:16PM (#28624153)
ms is milliseconds
Re:How we got to LiveView by sodapopcan on Wednesday September 22, 2021 @09:36PM (#28624285)
Yep, which is what I meant in my comment you're replying to (as per my statement that devtools only report to the 0.001). But as pointed out by jclem, I'm probably wrong about microsecond response times anyway. I'm very likely thinking about the MICROseconds I see in dev, which of course doesn't count :) But with the heroku link above, I am seeing as low as 1-3 MILLIseconds in Toronto, Canada.
Re:How we got to LiveView by jclem on Wednesday September 22, 2021 @09:27PM (#28624232)
One light-microsecond is about 300 meters, this must be milliseconds.

Edit: Just saw that this was already pointed out. Apologies, didn’t mean to pile on.

Re:How we got to LiveView by sodapopcan on Wednesday September 22, 2021 @09:40PM (#28624327)
I pointed out below that I actually DID mean microseconds but likely skewed by times I was seeing in dev. Hopefully it does not take away from my point that response times are still imperceptible when in roughly the same region (I'm seeing 1-3 milliseconds in the heroku-hosted LiveView app I linked below).
Re:How we got to LiveView by akoutmos on Wednesday September 22, 2021 @04:48PM (#28621583)
For a lot of the LiveView applications that I write (which is actually quite a few these days), I will usually lean on something like AlpineJS for frontend specific interactions, and my LiveView state is for things that require backend state.

For example, if I have a flag to show/hide a modal to confirm a resource delete, the show/hide flag would live in AlpineJS, while the resource I was deleting would live in the state of my LiveView.

This way, there are no round trips to the server over websocket to toggle the modal. Hopefully that example makes sense :).

Re:How we got to LiveView by cs44 on Wednesday September 22, 2021 @06:08PM (#28622623)
I'm surprised to see so few mentions of AlpineJS. Personally, PETAL has become my de facto stack.
Re:How we got to LiveView by AlchemistCamp on Thursday September 23, 2021 @12:46PM (#28631691)
The main thing that's kept me from using Alpine in my serious projects is that it doesn't work with a strict CSP.
Re:How we got to LiveView by brainbag on Thursday September 23, 2021 @12:02AM (#28625096)
What is PETAL?
Re:How we got to LiveView by sarchertech on Thursday September 23, 2021 @12:15AM (#28625159)
Phoenix, Elixir, Tailwind, Alpine, and LiveView.

https://changelog.com/posts/petal-the-end-to-end-web-stack

Re:How we got to LiveView by iruoy on Thursday September 23, 2021 @08:01AM (#28627983)
The PHP equivalent would be the TALL stack (Tailwind, AlpineJS, Laravel and Livewire). Although Livewire just communicates over AJAX. The original Websockets version didn't make it.

I just found out that Livewire was inspired by LiveView.

Re:How we got to LiveView by sillysaurusx on Wednesday September 22, 2021 @05:00PM (#28621761)
It’s telling that every answer is “just deploy servers near your users.”

One of YouTube’s most pivotal moments was when they saw their latency skyrocketed. They couldn’t figure out why.

Until someone realized it was because their users, for the first time, were world wide. The Brazilians were causing their latency charts to go from a nice <300ms average to >1.5s average. Yet obviously that was a great thing, because of Brazilians want your product so badly they’re willing to wait 1.5s every click, you’re probably on to something.

Mark my words: if elixir takes off, someday someone is going to write the equivalent of how gamedevs solve this problem: client side logic to extrapolate instantaneous changes + server side rollback if the client gets out of sync.

Or they won’t, and everyone will just assume 50ms is all you need. :)

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @05:17PM (#28621942)
> It’s telling that every answer is “just deploy servers near your users.”

This isn't the takeaway at all. The takeaway is we can match or beat SPAs that necessarily have to talk to the server anyway, which covers a massive class of applications. You'd deploy your SPA driven app close to users for the same reason you'd deploy your LiveView application, or your assets – reducing the speed of light distance provides better UX. It's just that most platforms outside of Elixir have no distribution story, so being close to users involves way more operation and code level concerns and becomes a non-starter. Deploying LiveView close to users is like deploying your game server closes to users – we have real, actual running code for that user so we can do all kinds of interesting things being near to them.

The way we write applications lends itself to being close to users.

Re:How we got to LiveView by sillysaurusx on Wednesday September 22, 2021 @06:14PM (#28622694)
Imagine how painful HN would be if you upvoted someone and didn’t see the arrow vanish till the server responded. Instead of knowing instantly whether you missed the button, you’d end up habitually tapping it twice. (Better to do that than to wait and go “hmm, did I hit the button? Oh wait, my train is going through a tunnel…)

Imagine how painful typing would be if you had to wait after each keypress till the server acknowledged it. Everyone’s had the experience of being SSH’ed into a mostly-frozen server; good luck typing on a phone keyboard instead of a real keyboard without typo’ing your buffered keys.

The point is, there are many application-specific areas that client side prediction is necessary. Taking a hardline stance of “just deploy closer servers” will only handicap elixir in the long run.

Why not tackle the problem head-on? Unreal Engine might be worth studying here: https://docs.unrealengine.com/udk/Three/NetworkingOverview.h...

One could imagine a “client eval” code block in elixir which only executes on the client, and which contains all the prediction logic.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @06:59PM (#28623134)
You'd use the optimistic UI features that LiveView ships with out of the box to handle the arrow click, and you wouldn't await a server round-trip for each keypress, so again that's now how LiveView form input works. For posterity, I linked another blog where I talk exactly about these kinds of things, including optimistic UI and "controlled inputs" for the keyboard scenario: https://dockyard.com/blog/2020/12/21/optimizing-user-experie...

While we can draw parallels to game servers being near users, I don't think it makes sense for us to argue that LiveView should take the same architecture as an FPS :)

Re:How we got to LiveView by sillysaurusx on Wednesday September 22, 2021 @05:25PM (#28622035)
> Deploying LiveView close to users is like deploying your game server closes to users – we have real, actual running code for that user so we can do all kinds of interesting things being near to them.

Then why do you start running forward instantly when you press “W” in counterstrike or quake? Why not just deploy servers closer to users?

Gamedev and webdev are more closely related than they seem. Now that webdev is getting closer, it might be good to take advantage of gamedev’s prior art in this domain.

There’s a reason us gamedevs go through the trouble. That pesky speed of light isn’t instant. Pressing “w” (or tapping a button) isn’t instant either, but it may as well be.

Re:How we got to LiveView by _6pvr on Wednesday September 22, 2021 @07:42PM (#28623468)
> Then why do you start running forward instantly when you press “W” in counterstrike or quake? Why not just deploy servers closer to users?

You do both? Game client handles movements and writes game state changes to a server, which should be close to the user to reduce the possibility for invalid state behaviors? You really haven't seen online games that deploy servers all over the world to reduce latency for their users? What?

Both web apps and games do optimistic server writes. Both web apps and games have to accommodate a failed write. Both web apps and games handle local state and remote state differently.

Re:How we got to LiveView by strken on Thursday September 23, 2021 @06:45AM (#28627455)
I read his post as a criticism of how little optimistic updating is done in web apps, and how bad the user story is. Why can't it be easy to build every app as a collaborative editing tool without writing your own OT or CRDT?
Re:How we got to LiveView by treis on Thursday September 23, 2021 @09:29AM (#28628827)
Because an occasional glitch when the client & server sync back up is acceptable in a game. Finding out that my order didn't actually go through is much worse. Especially since click button, see success, and close browser is an relatively common use case.
Re:How we got to LiveView by yencabulator on Thursday September 23, 2021 @04:26PM (#28634822)
Consider these two scenarios.

1. SPA with asynchronous server communication. A button switches to a spinner the moment you click it, and spins until the update is safe at the server. Error messages can show up near the button, or in a toast.

2. LiveView where updates go via the server. The button shows no change (after recovering from submit "bounce" animation) until a response from the server has come back to you. To do anything better, you need to write it yourself, and now you're back in SPA world again.

There's a reason textarea input isn't sent to a server with the server updating the visible contents! Same thing applies to all aspects of the UX.

EDIT: https://dockyard.com/blogs/optimizing-user-experience-with-l... talks about this. That'll handle things like buttons being disabled while a request is in flight, but it won't e.g. immediately add new TODO items to the classic TODO list example.

Re:How we got to LiveView by strken on Thursday September 23, 2021 @10:06AM (#28629345)
That's a deliberate UI choice, though, and it doesn't always make sense in non-transactional workflows. It's easy to wait for Google Docs to say "Saved to Drive", and going to a new page to save a document would be really disruptive to your workflow, for example.
Re:How we got to LiveView by Kiro on Wednesday September 22, 2021 @05:48PM (#28622345)
I remember this story but can't find it anywhere. If I recall correctly they deployed a fix that decreased the payload size. However, in doing so they actually opened the door to users with slow connections that were unable to use it at all before. So measured latency actually went up instead of down.
Re:How we got to LiveView by sillysaurusx on Wednesday September 22, 2021 @05:59PM (#28622509)
That’s the one! Where the heck is it? It’s one of my all time favorite stories, but it seems impossible to find; thanks for the details.
Re:How we got to LiveView by Kiro on Wednesday September 22, 2021 @06:09PM (#28622636)
Re:How we got to LiveView by sillysaurusx on Wednesday September 22, 2021 @06:20PM (#28622740)
YES! Thank you! I’ve seriously been searching for like five decades. What was the magical search phrase? “YouTube Brazil increase latency” came back with “How YouTube radicalized Brazil” and other such stories. (Turns out the article mentions “South America” rather than “Brazil”; guess my Dota instincts kicked in.)

Anyway, you rock. :)

Re:How we got to LiveView by Kiro on Wednesday September 22, 2021 @06:37PM (#28622913)
Thank you! It was impossible to find anything on Google since any variant of "youtube", "latency" etc showed results for problems with YouTube or actual YouTube videos talking about latency.

The trick was to use HN search: "youtube latency" and select Comments. First result was a comment on https://www.forrestthewoods.com/blog/my_favorite_paradox/ which links the story in the "Bonus!" section.

Re:How we got to LiveView by a-dub on Wednesday September 22, 2021 @06:38PM (#28622926)
> Mark my words: if elixir takes off, someday someone is going to write the equivalent of how gamedevs solve this problem: client side logic to extrapolate instantaneous changes + server side rollback if the client gets out of sync.

most games have the benefit that they're modeling the mechanics of physical objects moving around in the world and are having their users express their intentions through spatial movement. the first gives a pretty healthy prior in terms of modeling movement when data drops out and the latter can be fairly repetitive and thereby learnable and predictable.

whether or not user interaction behaviors can be learned within the context of driving web applications seems a little less clear, to me at least. it does seem like there are a lot more degrees of freedom.

Re:How we got to LiveView by janekm on Thursday September 23, 2021 @09:09AM (#28628557)
Nothing so complicated. All that's needed is a local cache so that when you type a new message in the chat window, you immediately see it appear when you hit submit (optionally with an indication of when the message was received by the peer). But there's quite a bit of tooling required to reliably update the local cache, run the code both in the client and on the server.
Re:How we got to LiveView by yencabulator on Thursday September 23, 2021 @04:33PM (#28634928)
Firebase does this brilliantly with Firestore queries. Any data mutation by the client shows up in persistent searches immediately, flagged as tentative until server acknowledges.
Re:How we got to LiveView by redbar0n on Saturday September 25, 2021 @01:57AM (#28650859)
> server side rollback

server controlled client side rollback, you mean?

Re:How we got to LiveView by kureikain on Wednesday September 22, 2021 @05:15PM (#28621923)
On modern internet, with some assumption, you can get to like 2x faster(in my case) when sending data over an *already establised* connection.

Example:

A full fresh HTTP connect from client to first byte take ~400ms(I'm in the US the server is in Europe). This includes: resolve dns, open tcp connection, ssl handshake etc...

But if the connection is already establish, it only takes ~200ms to first byte.

If I deployed the server in the same region, say US customer <-> US server, this came down to 20ms...

That means, it's good enough.

Not super ideal but It's a trade-off we're willing to make.

Re:How we got to LiveView by janekm on Thursday September 23, 2021 @09:10AM (#28628568)
LiveView (I think) already achieves this optimisation as both the initial content and any future updates come over the same persistent websocket connection.
Re:How we got to LiveView by ignoramous on Wednesday September 22, 2021 @04:46PM (#28621565)
Not OP, but:

> If latency is high, this can make for a poor user experience, the argument goes.

Deploy auto-scaling servers closer to your users: Use fly.io (or any other competent edge platform, really).

Re:How we got to LiveView by aabbcc1241 on Sunday September 26, 2021 @12:54AM (#28658498)
A better balance would be to build the webapp in hybrid mode, some logic can be run by client-side javascript. Only the event handlers that rely on data from the server needed to be sent to the server.

In this pixel paint demo, the state and reaction of "changing the pen color" can happens locally: https://github.com/beenotung/live-paint/blob/dd3b370/server/...

Re:How we got to LiveView by a_c on Thursday September 23, 2021 @08:17AM (#28628095)
I had never used LiveView and tangential to the latency consideration here. Two applications that I think can be enabled by siphoning all events to server are server-side analytics and time travel debugging (or reconstruction of a session). I am so glad to learn of this tool and definitely giving a try in my next project
Re:How we got to LiveView by ec109685 on Thursday September 23, 2021 @12:09AM (#28625133)
Here's a demo that illustrates that delay: https://breakoutex.tommasopifferi.com/

Agree it's super neat framework and hope a client side implementation can be written to "stage" the change.

Re:How we got to LiveView by andy_ppp on Thursday September 23, 2021 @02:30AM (#28625781)
Chris said in a different comment optimistic ui updates already exist…

Here’s the link: https://dockyard.com/blog/2020/12/21/optimizing-user-experie...

Re:How we got to LiveView by neillyons on Thursday September 23, 2021 @07:00AM (#28627560)
Here is an article about updating the UI without waiting for the roundtrip to the server.

http://blog.pthompson.org/liveview-tailwind-css-alpine-js-mo...

Re:How we got to LiveView by jherdman on Wednesday September 22, 2021 @04:41PM (#28621494)
Hi Chris.

We've been using LiveView to build a new app at Precision Nutrition and are largely quite happy with it so far.

One concern we keep coming back to is that of the need for constant connectivity in order for the app to work. I'll throw up the disclaimer here that I've not spike on how to handle network disconnects. That said, we've had a few of our internal users lose their connection to the web socket, and the app just beach balls. You can't do anything. Another example we keep coming back to is a user going onto a subway.

How do you envision spotty connections being handled long term?

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @07:13PM (#28623250)
LiveView will automatically recover the connection, but you are correct it requires a connection to allow interactivity, but this isn't different from being unable to post a tweet while driving under the subway. The interesting thing about the subway usecase is even google docs last I checked will go into read-only mode when the connection is lost, so I don't consider this scenario particular different than the status quo.

LiveView adds a `phx-disconnected` class, which is what I assumed you mean by beachball, and interactions are paused while the user awaits the UI to tell them they are good. This is all driven by your CSS and you can also hook into the connection life-cycle with a few lines of JS, so the app should be telling the user "Reconnecting..." vs it appearing broken, so this is really up to your UX folks. By default new phx apps make use of the topbar library so any page loading event or dropped connection will show the loading bar/spinner up top.

As far as spotty connections go, when I try simulating 30% packet loss, my LiveView WebSocket connections have no perceptible degradation, so it's hard to say where the cut off is. You can also fall back to long-polling which may benefit very edge users, but I would only do so if absolutely necessary.

Having said all that, one thing we are upfront about in general is LiveView is obviously not a good fit applications that require offline support :)

Re:How we got to LiveView by iainmerrick on Wednesday September 22, 2021 @07:56PM (#28623595)
this isn't different from being unable to post a tweet while driving under the subway

In principle, your Twitter client could remember the state locally, let you keep working, and just keep trying to sync.

In practice... most apps are really bad at working offline, so just handling the disconnection and reconnection in a robust and consistent way is already much better than average!

Re:How we got to LiveView by wokwokwok on Thursday September 23, 2021 @04:01AM (#28626444)
> it requires a connection to allow interactivity, but this isn't different from being unable to post a tweet while driving under the subway. The interesting thing about the subway usecase is even google docs last I checked will go into read-only mode when the connection is lost...

I think that 'read-only mode' and 'can't interact at all' mode are not the same.

I often have google news open when the train vanishes down a tunnel and keep scrolling down reading headlines until we're out the other side.

If a website freezes on me, I close it.

> Having said all that, one thing we are upfront about in general is LiveView is obviously not a good fit applications that require offline support :)

Not a good fit is rather charitable...

It becomes totally unresponsive and totally unusable in any offline or high latency situation (trains, stadiums, remote areas) right?

I know, and I've read your responses that 'well, all websites have to interact with a server eventually, so it's pretty much the same as that only better...' but, well... when you build websites like this, that's why product managers say "no, we don't want a website, we want an app".

Re:How we got to LiveView by chrismccord on Thursday September 23, 2021 @08:51AM (#28628379)
> Not a good fit is rather charitable.

s/obviously not a good fit/non-starter :)

> I think that 'read-only mode' and 'can't interact at all' mode are not the same.

I agree, but it depends on the application. LiveView doesn't "freeze", but the content on the page is not going to continue updating or be interactive. This indeed limits some applications that want to allow the user to continue editing a document, but your example of a news site absolutely still functions fine for read-only offline.

> It becomes totally unresponsive and totally unusable in any offline or high latency situation (trains, stadiums, remote areas) right?

Yes, just like the vast vast majority of web applications today, including the vast vast majority of SPAs that could, in theory, work offline, but don't because of the added complexity on the client and server, state syncing, conflict resolution, etc. If working under the offline condition is a hard requirement, LiveView is out full stop. But even for SPAs, this is an opt-in feature today that few choose.

Re:How we got to LiveView by jherdman on Wednesday September 22, 2021 @08:13PM (#28623741)
Thank you for your response, Chris. It's much appreciated!
Re:How we got to LiveView by mrkurt on Wednesday September 22, 2021 @05:55PM (#28622451)
I've been experimenting with some progressive enhancement style HTML. You can build forms that post the "normal" way, then get the full liveview experience when the socket is mounted.

If an app can be reduced to just CRUD, I think it works very well.

Re:How we got to LiveView by nightpool on Wednesday September 22, 2021 @04:02PM (#28621101)
I've tried to get into Phoenix a few different times, but I've always been stymied by the unfamiliarity of Elixir's syntax, especially codebases that made heavy use of composition and guard clauses, meaning that the business logic was scattered across a half-dozen different files which had to be read in sequence to understand a single web request. This was a big let-down from the (to my mind) very straight-forward nature of MVC code and project structure that Rails pioneered. Do you have any tips for structuring Phoenix projects or approaching these kinds of codebases?
Re:How we got to LiveView by sodapopcan on Wednesday September 22, 2021 @04:40PM (#28621489)
I'm not sure I follow. Phoenix is also MVC and its request model is far simpler than Rails'. In Rails we have controllers, we have callbacks (or "filters" as they are called now), and we have "middleware". That's three concepts right there! In Phoenix, we have a connection struct that flows through a pipeline of "plugs". Plugs are just functions that transform said connection. Each part of the request pipeline is implemented as a plug. You can create your own plugs and "plug" them in where you see fit. Read more here: https://hexdocs.pm/phoenix/plug.html

Of course, LiveView isn't MVC in the classic sense, but it still uses plugs. Its goal is to simplify the SPA which I'd say it does a particular good job of.

[Edited to fix part of a sentence I deleted by accident]

Re:How we got to LiveView by dnautics on Wednesday September 22, 2021 @07:26PM (#28623345)
> Do you have any tips for structuring Phoenix projects or approaching these kinds of codebases?

Ignore the "View" modules. Put nothing in them. You can also eschew the "Context" modules for your database stuff, and just use Ecto functions directly, though, if you do get into the habit of using Context modules, it will make your life easier to have a unified point of view that abstracts away, e.g. caching, or, if you decide to go full CQRS/event-driven, if you need to send a copy of your data to a datalake, etc, etc.

Actually LiveView tends to have less module-indirection than "deadview"s.

If you prefer to have simple apis, you can just drop phoenix altogether and just stick to Plug. This will give you a ruby/sinatra-style experience that may be more your style, and, IMO, a good way to learn elixir. I did this for a long time before finally giving in and learning phoenix. I turned out OK.

Re:How we got to LiveView by erinan on Wednesday September 22, 2021 @06:00PM (#28622512)
This has most likely to do with the codebase itself rather than with Elixir or Phoenix in your case.

And having to go through a few files to understand how a request is handled is not out of the ordinary in an app, especially if it's grown over the years?

Re:How we got to LiveView by dnautics on Wednesday September 22, 2021 @11:21PM (#28624908)
Tbh Phoenix has a lot of boilerplate and some... Opinions that make the codepath slightly more complicated (often for good reason... that might not apply to all use cases) in the default project.

For example:. What exactly is the distinction between an endpoint and a router?

Re:How we got to LiveView by 0x000000001 on Thursday September 23, 2021 @07:27AM (#28627738)
Endpoint == instance of phoenix webserver. Changing things in the endpoint gives you WAF-like control and you can do some early footwork here and store useful data in conn[:private] for you to use later in the modules called in your router

You can have multiple routers. I just built a thing where foo.com uses one router for the main site and *.foo.com is something else.

Re:How we got to LiveView by dnautics on Thursday September 23, 2021 @09:26AM (#28628774)
Point is, they are just plugs. You can put routes in an endpoint, it'll work just fine. The distinction is just a -often useful- prescriptive opinion by Phoenix. (Plug does not split between endpoints and routers)
Re:How we got to LiveView by 0x000000001 on Thursday September 23, 2021 @10:56AM (#28630070)
very true, but the abstraction is pretty useful
Re:How we got to LiveView by dnautics on Thursday September 23, 2021 @12:13PM (#28631201)
it's useful if your project gets very large. It is a non-negligible cognitive cost when your project is very small and you are new to Elixir and Phoenix
Re:How we got to LiveView by yewenjie on Wednesday September 22, 2021 @04:39PM (#28621469)
Hi, really excited about the new release - Heex and Esbuild support is fantastic.

Do you think it is possible for newcomers to pick up Phoenix and at the same time learn how frameworks work? For example, FastAPI [0] is a widely extensive Python framework yet its documentation essentially is just a long tutorial which explains basic web-development concepts while teaching its core. OTOH, almost all Phoenix learning material I have come across so far are targeted to experienced devs (especially Rails).

I really love that Phoenix is opinionated but I feel like there should be some ways to learn about the rationale behind those choices, without having 10 years of development intuition.

[0] https://fastapi.tiangolo.com/

Re:How we got to LiveView by PKop on Wednesday September 22, 2021 @05:51PM (#28622369)
Take a look at these courses on Elixir/OTP[0] and Phoenix LiveView[1] from Pragmatic Studio. Both of them together I felt gave a well paced overview of elixir servers, and Phoenix framework from a good starting point even for beginners as you seem to be looking for. There's a combo price deal if you by both courses.

[0] https://pragmaticstudio.com/courses/elixir

[1] https://pragmaticstudio.com/courses/phoenix-liveview

Re:How we got to LiveView by chrismccord on Thursday September 23, 2021 @08:55AM (#28628417)
It's absolutely possible, but you are right our docs and guides are more tailored to folks already familiar with web development. I would love to see more Elixir and Phoenix content for someone who has never written a program before. I do think we'll start seeing more of these kinds of efforts, but it's the nature of the age of the ecosystem and adoption cycle that content is initially tailored to more advanced users.
Re:How we got to LiveView by neillyons on Thursday September 23, 2021 @06:50AM (#28627490)
This article really helped me. It basically builds Phoenix from the ground up. Starting with "hello world" in the terminal.

http://www.petecorey.com/blog/2019/05/20/minimum-viable-phoe...

Re:How we got to LiveView by ignoramous on Wednesday September 22, 2021 @05:17PM (#28621935)
Hi Chris,

A someone who's familiar with Kotlin, I can see how Erlang's processes and mailboxes would work. The question I have is, you mention Phoenix maxed out available FDs but RoR would have struggled. I didn't quite get what those fundamental differences are that prevent RoR/Ruby from scaling-up io-bound workloads as effortlessly as Elixir/Erlang, given you point out that sync.rb was built upon a similarly capable event-io lib.

Also, if I may, what do you make of your former employers 37 Signal's turbo (hotwire) with RoR? Does the vision you have for Phoenix with LiveView match what you see them doing with hotwire? How do the solutions compare if you have had a chance to take a look?

Thanks.

Re:How we got to LiveView by strzibny on Thursday September 23, 2021 @10:03AM (#28629308)
I am not Chris, but maybe I can answer the Hotwire and LiveView difference.

Hotwire is building stuff from regular HTTP requests (ala AJAX) and uses WebSockets only for Turbo Streams. LiveView is all on WebSockets.

You can think of Hotwire as being stateless and stateful when required. LiveView is stateful.

Hotwire exchanges HTML snippets at various length whereas LiveView tries to do a very minimal diff for an update.

WebSockets would be faster for your regular updates, but you need to keep a connection open. In other stacks this might not be ideal, but it's what Beam is made for.

Re:How we got to LiveView by losvedir on Wednesday September 22, 2021 @05:13PM (#28621892)
1. LiveView looks incredible! But Phoenix is also great at standard JSON APIs. How do you think about the decision between using LiveView vs a SPA with a Phoenix API backend? I'm not too sure about the limits or future vision of LiveView. Do you think there's a place for SPAs, or is the goal for LiveView to be able to replace them in almost all use cases?

2. What's your dev environment like? VSCode? What extensions, etc?

3. Excited to see you at fly.io! I think I saw a tweet about them wanting to make deploying Livebooks (built on LiveView) easy. Any news on that front?

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @10:42PM (#28624692)
1. Thanks! You are right Phoenix also great for APIs, and this story is pretty much baked as far as Phoenix specific features go. There's absolutely a place for SPAs, and the JavaScript ecosystem has number of great options. Anything requiring offline support is obviously out for LiveView, as well as highly complex UIs, tho that is pretty vague. For example, I wouldn't build Google Docs or Google Maps with LiveView, but as we've seen with Livebook, you can do a shocking amount of complex things with a LiveView application and a few escape hatches to JS. We're still finding out where the bounds are.

Our goal isn't to replace SPAs, but I do think we'll obviate them for a large class of applications.

2. VSCode with VIM keybindings. I bounce from vim/emacs/vscode (all w/ vim emulation), but vscode has stuck pretty well for the last couple years. Much to my chagrin, it's faster than terminal emacs.

3. No news quite yet, but we're working on it. Stay tuned!

Re:How we got to LiveView by ethnt on Wednesday September 22, 2021 @03:50PM (#28620931)
Thanks for your work! One question I had is about when it comes to expanding beyond the web, what are the solutions available with Phoenix? For example, if I'm making a web app using LiveView, do I need to make a second app for my API for an iOS app?
Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @04:19PM (#28621218)
We structure Elixir applications differently than a lot of platforms. Phoenix is not your app – it's just one thing that slots into your Elixir application's supervision tree. So you can run one Phoenix web server or multiple in a single Erlang VM, and nothing changes. Your Phoenix endpoint isn't global, so it will happily sit alongside several, or it will happily serve a single web server to any number of Phoenix routers serving different APIs.

So to answer your question directly, you could either add your JSON or GraphQL API directly in the same router that serves your LiveViews, or you could create a router specific to the API, or you could introduce a completely separate Phoenix endpoint and router that starts a 2nd web server. Both would boot as part of the app serving different ports. Phoenix remains a great choice for native clients if we're talking JSON/GraphQL, but because we also have native channels clients in objc/swift. Hope that helps!

Re:How we got to LiveView by spiderice on Wednesday September 22, 2021 @04:02PM (#28621091)
I was actually just searching for this same thing on Google. I recently started a new project that LiveView would have been great for, but the fact that I need a native iOS/Android app caused me to go with Socket.IO instead for the backend. It seems likely to me that there is a way to use Phoenix channels with web, iOS, and Android.. but there isn't a lot of good information on doing it that I've been able to find.

Edit: I realize you could just use regular web sockets with Phoenix to do what Socket.IO does. But my confusion comes from actually getting it all to play nice with a LiveView front end, as well as a native app front end.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @04:25PM (#28621299)
Phoenix channels is similar to socket.io, except we multiplex the channels with their own events, vs socket io that creates a single bidirectional "channel" with events. So you can think of channels as namespaced socket.io, with the server side allowing isolated and concurrent message handlers to live.

The channel docs give a solid overview of the server side, and we have a listing of third-party channels clients for most platforms here:

https://hexdocs.pm/phoenix/1.6.0-rc.1/channels.html#client-l...

Re:How we got to LiveView by klohto on Wednesday September 22, 2021 @04:17PM (#28621199)
Out of my head (just amateur in Phoenix right now) you could just leverage the API endpoints in Phoenix and implement the iOS and Android frontend with them. The Views are decoupled. So you can have the business logic, as you would normally do, inside Phoenix, then the API on top of this logic, and then you could either implement the whole LiveView workflow on top of the API or just directly on top of the business logic (if you’re feeling kinky but it invalidates the architecture Phoenix sets up for you).

The Getting Started guide on Phoenix has a lot of useful material even for your use case. I might be missing something crucial though :)

Re:How we got to LiveView by hervature on Wednesday September 22, 2021 @03:55PM (#28621014)
Hey Chris, excellent work. Very excited about 1.6 and LiveView. If you update your Programming Phoenix, I would certainly pay again.
Re:How we got to LiveView by yeskia on Wednesday September 22, 2021 @11:11PM (#28624862)
Yeah, would love to see an updated book to dive back in for 1.6.
Re:How we got to LiveView by tclancy on Wednesday September 22, 2021 @04:27PM (#28621322)
Seconded!
Re:How we got to LiveView by davidw on Wednesday September 22, 2021 @04:26PM (#28621317)
Business-wise, what do you think the sweet spots are for LiveView, Phoenix and Elixir right now? I love the BEAM ecosystem (I've been using it since 2004, on and off), but for a lot of places, Rails is still a great place to start. What kinds of applications have you seen where all the BEAM features just make Phoenix et al not just a little snappier, but a clear winner?
Re:How we got to LiveView by innocentoldguy on Wednesday September 22, 2021 @06:53PM (#28623085)
The sweet spots for me are:

1. It is much easier to trace things through the entire Phoenix stack than it is in Rails. It is also much easier to add things to the Phoenix stack using plugs.

2. Elixir is concurrent, whereas Ruby is not, so when performing long-running processes, you can just do them in Elixir/Phoenix without having to rely on workarounds like Sidekiq, Resque, RabbitMQ, etc.

3. Writing multi-threaded applications is much easier in Elixir than many (if not all) OO languages.

4. Pattern-matching for variables and functions, and binary pattern-matching for parsing text.

5. Mix.

6. BEAM, OTP, and supervision trees.

Re:How we got to LiveView by davidw on Wednesday September 22, 2021 @06:59PM (#28623133)
Looking more at things like #2. Sidekiq isn't terrible though, and if you get big enough, you're going to want some more management than just spawning a BEAM process to do something. What have people settled on for that with Elixir/Erlang?
Re:How we got to LiveView by hanrelan on Wednesday September 22, 2021 @07:08PM (#28623211)
You could use something like oban: https://github.com/sorentwo/oban
Re:How we got to LiveView by tptacek on Wednesday September 22, 2021 @09:14PM (#28624139)
Sidekiq is great, but it is a thing you have to think about (in particular, how you're shuttling state from workers to a place where front-end can see it). The big win with Phoenix as I understand is not having to think about it at all: it has a natural expression in the language and the platform, and that expression is performant.
Re:How we got to LiveView by davidw on Thursday September 23, 2021 @12:34AM (#28625245)
If it's just a small fire and forget thing in Erlang, you can just spawn the process, sure. My point is that once people start to care about what happens with those background jobs, you probably need some infrastructure around them, and then the Erlang thing might start to resemble Sidekiq a bit more.
Re:How we got to LiveView by joelbluminator on Thursday September 23, 2021 @04:10AM (#28626498)
This.

"When we want to have more control, i.e. persistence on disk, a workers pool, retries, among other things, there are several popular solutions:

Oban: a robust PostgreSQL-based queue backend process system. It has a UI in its pro version Exq: a Redis-based Resque and Sidekiq compliant processing library. It has an open source UI exq_ui verk: same as Exq. Is is compatible with Resque and Sidekiq job definitions"

https://sipsandbits.com/2020/08/07/do-we-need-background-job...

So basically sounds to me like Elixir is doing pretty much the same thing as Ruby. We usually do want more control and disk persistence, so...

Re:How we got to LiveView by joelbluminator on Thursday September 23, 2021 @04:00AM (#28626440)
Sidekiq is not a workaround. This is a myth. Most companies need to persist their jobs (what happens during deployments or when a process dies? do u just let all the job info disappear?) and have some kind of queue system. Even Elixir has some redis backed queues. BEAM, OTP, concurrency, this whole thing is solved with the current fashion of devops teams and kubernetes. It doesn't really matter what tech stack you use anymore it can quite easily scale. Our devops team is 2-3 people and they're scaling our Rails architecture easily. Our scale is quite big since we're a b2c company and most of their effort isn't even on scale but on making deployments easier and troubleshooting all kinds of dev problems / pager duty alerts. They would do the same amount of work if they were doing that with Elixir. If you're hitting Whatsapp scale yes Ruby is less than ideal. Could we stop pretending like the challenges of 5 companies are what most devs need to go through?
Re:How we got to LiveView by 0x000000001 on Thursday September 23, 2021 @07:32AM (#28627770)
In Elixir you'd use Oban instead of sidkiq and you get more performance and it scales out horizontally with your app. Each new instance of your app is essentially a new sideqik server as a bonus

edit: > BEAM, OTP, concurrency, this whole thing is solved with the current fashion of devops teams and kubernetes.

This is a hilarious statement which I hope is satire

Re:How we got to LiveView by innocentoldguy on Thursday September 23, 2021 @11:53AM (#28630946)
I don't see BEAM and OTP as being synonymous with Kubernetes. They have some overlaps but they aren't drop-in replacements for each other. If anything, they are complimentary technologies.

The advantages of BEAM and OTP are that I can spawn new concurrent processes throughout a cluster and then use the actor model to send direct messages to those processes from any other processes, regardless of where the sender and receiver happen to be. I can also easily configure Behaviours so they automatically run on either a single node or every node in the cluster, depending on what they are doing.

In both cases, if a node goes down, Elixir will automatically restart any affected processes on another node. When a process has an issue, I can surgically handle that issue at the individual process level. Kubernetes doesn't handle problems that granularly.

One advantage of Kubernetes is autoscaling. OTP and BEAM don't do that.

By using libcluster, you can combine Kubernetes and BEAM/OTP and get the best of both worlds.

Re:How we got to LiveView by joelbluminator on Thursday September 23, 2021 @07:37AM (#28627796)
I don't know about Oban. I don't think it's bad design for the workers to be separate from your main app like in Sidekiq (they do 'require' the app but they are essentially separate from the servers). Anyway making this point as a huge win for Elixir over Ruby seems really exaggerated to me.
Re:How we got to LiveView by 0x000000001 on Thursday September 23, 2021 @10:55AM (#28630064)
It prevents unnecessarily moving data around. And if you're running the whole stack on the same server with Sideqik you're dealing with interrupts and memory copies between processes; in Elixir it's all within the same allocated memory and nothing gets copied. Plus it's another service you don't have to monitor because it's automatically monitored by BEAM.
Re:How we got to LiveView by joelbluminator on Thursday September 23, 2021 @11:42AM (#28630800)
What if you want to scale your job workers and your servers separately?
Re:How we got to LiveView by 0x000000001 on Thursday September 23, 2021 @03:20PM (#28633928)
Oban will let you choose which servers the jobs can execute on, and you could do the same with your own app code

> Queue Control — Queues can be started, stopped, paused, resumed and scaled independently at runtime locally or across all running nodes (even in environments like Heroku, without distributed Erlang).

Re:How we got to LiveView by davidw on Thursday September 23, 2021 @12:14PM (#28631227)
I think it's nice that you can run everything in the same server. If you're scaling, and want to split everything up, that's a "nice problem to have", but it's convenient if you can just run everything in the same application/codebase when you're getting started.

I do agree with you that's not a huge win compared with Rails, but it is nice to have. I think you'd have to look more at something like "lots of concurrent, long-lived connections" for the real wins over Rails for the BEAM ecosystem. I mean, you can do that in Ruby if you want to, but it's going to be cleaner and simpler with Elixir/Erlang.

Re:How we got to LiveView by turtlebits on Wednesday September 22, 2021 @05:43PM (#28622265)
Just getting started into Liveview, what confuses me is the proper way to integrate javascript. The JavaScript interoperability documentation page isn't really helpful.

A simple case for me is using hotkeys to submit a form. Couldn't figure out a way to trigger a phx-submit from a onkeydown handler.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @07:48PM (#28623514)
If you think the docs can be improved, please let us know. You can also find us on elixir-slack or elixirforum.com to ask for help. This should get you started:

    //<input type="text" name="body"  phx-hook="SubmitOnEnter"/>

    let Hooks = {}
    Hooks.SubmitOnEnter = {
      mounted(){
        this.el.addEventListener("keydown", e => {
          if(e.key === "Enter"){
            this.el.form.dispatchEvent(new Event("submit", {bubbles: true}))
          }
        })
      }
    }

    ...
    let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, ...})
Re:How we got to LiveView by jakeva on Wednesday September 22, 2021 @07:32PM (#28623392)
I might try setting a mounted hook on the element with something like

  this.el.addEventListener('onkeydown', function (event) {
      this.el.dispatchEvent(new Event('change', { 'bubbles': true }))
    }, true);
Re:How we got to LiveView by jarpineh on Wednesday September 22, 2021 @04:36PM (#28621437)
Hi.

I got a couple of things:

I seem to remember in the original announcement presentation there was a demo of SVG being updated inside a page 60 times per second. All from server. Did this actually become feasible? I’m thinking graphs and maps with live data. I might not need as smooth animation there. Though that could make for nice dashboards.

Other bit that interests me is web apps for long running tasks. What’s the story in Phoenix and Elixir land for handling external shell processes from web requests? I’m trying to do lightweight job control without investing into separate systems for processing pipelines, CI/CD and the like.

Thank you for Live View. It continues to be an inspiration even though I haven’t yet had a chance to dive into server side of it.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @07:25PM (#28623341)
The 60fps rainbow works as a fun stress test demo, but really you should not be pushing events down the wire every 16ms to animate something on the client :)

That said, you are right that SVG charts/maps are a surprisingly fantastic fit for LiveView. You could actually render a fully interactive and dynamically updating chart by only sending SVGs – and it will probably send less data than hydrating the same client-side chart with JSON! Check out the Context Chart lib for some examples. They have some links running LiveView examples if you scroll down: https://contex-charts.org

> What’s the story in Phoenix and Elixir land for handling external shell processes from web requests

Great story here thru erlang ports. I'm a big fan of the Porcelain library which wraps ports with some nice features on top: https://github.com/alco/porcelain

Re:How we got to LiveView by jarpineh on Thursday September 23, 2021 @01:40PM (#28632460)
Hey, thanks a lot. These are great tips. Context Charts look really good and lightweight to run. Porcelain seems verty promising. Guess I’ll start with one of the tutorials elsewhere in the thread. Good info here all around. Much appreciated.
Re:How we got to LiveView by giancarlostoro on Wednesday September 22, 2021 @03:47PM (#28620904)
I’m in love with LiveView havent done much Elixir yet but I do Django and have done ASP .NET in the past. I think its a brilliant concept. The only thing kind of holding me back on using Phoenix with personal projects and ideas is really the authentication stuff not being built-in (or when I looked I got this impression). I’m curious do you ever see Phoenix being fully supporting all the vitals or was your decision not to include authentication based on modern approaches differing like JWTs and such? Curious I am definitely going to use it in the future. As a backend nerd I always held love for Erlang and I think Phoenix / Elixir are my real way into the ecosystem.
Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @03:51PM (#28620959)
The Phoenix 1.6 release candidate has been out for a few weeks, and we now include a `phx.gen.auth` generator for a fully bootstrapped authentication solution: https://hexdocs.pm/phoenix/1.6.0-rc.1/mix_phx_gen_auth.html
Re:How we got to LiveView by giancarlostoro on Wednesday September 22, 2021 @04:32PM (#28621392)
Nice! I'm glad to see this, I'll definitely see about trying this out soon then. So I guess its really just a matter of time while Phoenix grows. Although from what I've seen it seems to have everything else I need.
Re:How we got to LiveView by ashton314 on Wednesday September 22, 2021 @03:49PM (#28620927)
There's been some progress on this front, I believe:

- https://hexdocs.pm/phx_gen_auth/overview.html

Re:How we got to LiveView by whitepoplar on Wednesday September 22, 2021 @04:27PM (#28621332)
If one wanted to learn LiveView today, what's the best resource to learn? Also, will there be improvements to the LiveView latency story (if it's even possible) when providing a service to a global audience? Thanks for all your work!
Re:How we got to LiveView by innocentoldguy on Wednesday September 22, 2021 @06:38PM (#28622928)
Someone else already mentioned this in a separate thread, but Pragmatic Studio's courses on Elixir and LiveView are outstanding. They're not free but they're worth the cost. You can get both for around $200 if you buy their Pro Bundle.

https://pragmaticstudio.com/courses/elixir

Re:How we got to LiveView by mrkurt on Wednesday September 22, 2021 @04:40PM (#28621478)
Non technical Fly.io founder here: LiveView and Elixir work very well distributed all over the world. Here's an example app I fumbled my way through to show it in action: https://liveview-counter.fly.dev/
Re:How we got to LiveView by tptacek on Wednesday September 22, 2021 @04:41PM (#28621499)
"Non-technical Fly.io founder", who do you think you're kidding? You have more commits than me in the last week.
Re:How we got to LiveView by whitepoplar on Wednesday September 22, 2021 @04:52PM (#28621638)
Haven't played around with Fly yet, but it seems amazingly well-suited to LiveView apps and y'all seem like great people in general. Is there a Fly solution for if someone needed a big swinging...database? I guess one fear is getting locked into Fly + LiveView given latency concerns with alternative hosting providers, but outgrowing Fly's database offerings.
Re:How we got to LiveView by mrkurt on Wednesday September 22, 2021 @04:56PM (#28621684)
Our Postgres is pretty great up to about 500GB. We'll be pushing that higher over the next year, but we have several customers using Crunchy Data (https://www.crunchydata.com/products/crunchy-bridge/) in conjunction with their Fly.io apps.

We intentionally give you super user access to your DBs so it's easy to migrate or spin up your own replicas. Our bet is that _most_ people won't outgrow our Postgres but having an escape hatch is still very comforting.

We previously worked on Compose.com. We, at least, understand how to manage huge databases when the time comes.

Re:How we got to LiveView by whitepoplar on Wednesday September 22, 2021 @05:01PM (#28621766)
Sounds like customers are in good hands!
Re:How we got to LiveView by PKop on Wednesday September 22, 2021 @05:53PM (#28622418)
Will there be a simpler quick start deploy process for LiveView coming soon? (last I looked at the tutorial it seemed a little tedious compared to other languages/platforms)
Re:How we got to LiveView by scraplab on Wednesday September 22, 2021 @04:27PM (#28621323)
Hi Chris - this is superb, really pleased to see LiveView getting so much attention, and thanks for all your hard work.

Can you talk a little about the current story with deployments and managing state across/during those?

Obviously Erlang/OTP supports hot upgrades, but those are hard to design correctly and not supported by container/VM environments like Heroku and (I presume?) Fly.io.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @11:35PM (#28624962)
Hot upgrades are a powerful and essential feature – when you have hard requirements for it. As you said, hot upgrades aren't simple and introduce a lot of work to get right. I like to tell folks, imagine you are building a pusher.com competitor, so your customers are paying for you to host active connections for their end-users. In this scenario, bouncing hundreds of thousands of connections for a cold deploy is a terrible offering because your clients are paying you or that reliable wire to their user's browser. Hot upgrades makes total sense here. Equally, if you're building a game server in Elixir, you likely don't want to teardown and rebuild your world state and bounce connected players.

So you opt-in to this complexity when you have a clear requirement for it. They other key point in this, is in either hot upgrade or cold deploy cases, you still have to design your stateful system to recover from complete restart. Servers catch on fire and things go bad sometimes, so the cold deploy approach of rebuilding the state on restart is not only completely viable by itself, but you're doing it anyway even with hot upgrades. Hope that helps!

Re:How we got to LiveView by ramchip on Wednesday September 22, 2021 @08:39PM (#28623916)
You can store state client-side. Say you have a view to edit users, with a modal dialog. A typical LiveView app will change the URL when you open the modal, so it's like /users?action=edit&user=bob. When a server goes down the client reconnects, and the LV receives the URL params in its handle_param callback, so it can recover the earlier state. Forms recover automatically in a similar way.

With this and a DB to store permanent data, an LV app can be deployed just like any other standard container app without user impact.

Re:How we got to LiveView by modal-soul on Wednesday September 22, 2021 @04:45PM (#28621546)
If LiveView is backed by PubSub, then I think you can offload persistence to Redis.
Re:How we got to LiveView by ramchip on Wednesday September 22, 2021 @08:53PM (#28624002)
LiveView in its standard configuration does not use Redis, it uses built-in Erlang distribution. But you can use Redis if you want to or if direct connections between nodes aren't possible.
Re:How we got to LiveView by slydo on Thursday September 23, 2021 @01:42PM (#28632484)
Hi Chris, two questions about phoenix and liveview.

I would like the web app to have good offline support and use localstorage for backing when the connection goes down (re-upload when connection is back up). It it in anyway feasible to add some middleware to the client connection handling of liveview so that it still plays well with it's features?

I've read that it is possible to drop in some bits of JS here and there into the liveview powered page. Is it also possible to do it the other way around and go to drop in liveview "components" into an existing SPA? Throwing away my existing SPA code is quite a loss, but the liveview appeal is certainly there for other parts of the website.

Thanks for the great work on phoenix, it looks quite attractive.

Re:How we got to LiveView by staticelf on Wednesday September 22, 2021 @04:31PM (#28621380)
Are you guys looking into the Web Transport protocol for the future? Right now you have to tunnel the websocket connections over http2 and it will probably be the same for http3 afaik.

I know there is this work in progress (https://w3c.github.io/webtransport/) and websockets are probably fine for a long time but sooner or later (unless there is an update to websockets) it will probably be faster to just do normal http requests and listen on server sent events.

What are your thoughts for Liveview for the future? Will it forever stay on websockets or would you be open to change the underlying technology if / when new stuff becomes available?

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @11:42PM (#28624994)
Phoenix Channels (which LiveView is built on) is transport agnostic, so as soon as we can open a pipe from the browser's JS environment, and listen on the server, we could have a `Phoenix.Transports.WebTransport`. All the existing user-land code and LV apis remain unchanged :)
Re:How we got to LiveView by staticelf on Thursday September 23, 2021 @03:21AM (#28626173)
That is something I suspected. When I first saw your talk about LiveView on youtube my mind was completely blown away.

It is such an awesome technology.

Re:How we got to LiveView by ashton314 on Wednesday September 22, 2021 @03:44PM (#28620879)
Hey Chris! First, a huge thank you for making this. I started playing around with LV v0.2 or something. It's definitely come a long way since then!

I've read the blog post about getting 2 million concurrent connections on a single server with minimal tuning. That's pretty mind blowing. How does that compare will real-world scalability with LV? Like, can I actually have 2 million people looking at a LV simultaneously? I think the worry I hear most is whether or not LV scales. I've personally never run into any problems at all, but the projects I've built with LV haven't been the highest-traffic apps.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @04:05PM (#28621130)
My pleasure! LiveView is built on Phoenix channels, so it has the same scaling characteristics of a channels application. We had 2 million connections, but what that means is those 2 million websocket connections each started a channel to join the chat room, so we were running full-blown channels in that load test. For LiveView, the main consideration will be memory usage since you are likely to keep more state than something offloading some state to a JavaScript or native UI. That said, check out our docs on `temporary_assigns`, which allows you to specify which template state you hold on to, and which you only need the first time and can throw away (or fetch on demand) later.

The other thing to consider load-wise is the very state that you can now keep in memory allows you to reduce system load. Instead of fetching and authenticating the current user for every interaction, you do that one time for the lifetime of the visit. Database load is drastically reduced and you don't spend CPU cycles doing token verification. So while there's a cost to holding state, in general this will allow you to do much less work than a stateless application.

Re:How we got to LiveView by foofoobar on Wednesday September 22, 2021 @03:48PM (#28620906)
Thanks for your work, this really looks promising!

One question I keep thinking about. What if I want to still use React on the frontend, does it still make sense to use Phoenix for the backend then or am I throwing all benefits over board then?

Re:How we got to LiveView by ketzo on Wednesday September 22, 2021 @04:30PM (#28621367)
As a personal testament: I did this for a side project, and it worked perfectly. Phoenix does very well as "just" an API/backend environment.
Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @03:54PM (#28620992)
Phoenix is still fantastic for JSON and GraphQL apis. In fact, with GraphQL subscriptions, it's extremely well suited because how well we handle WebSockets and pubsub. The community has a robust GraphQL toolkit which works with Phoenix. It has long been 1.0 and has had a book published around it, so quite solid: http://absinthe-graphql.org
Re:How we got to LiveView by anonymousDan on Thursday September 23, 2021 @03:41AM (#28626313)
How do you handle issues of consistency once you need to scale your app server across multiple nodes? Under the assumption that in the past much of this would be handled in the database, are there any guidelines regarding what state to maintain in the app server in order to avoid any issues? Or is this just a non-problem?
Re:How we got to LiveView by Omnipresent on Wednesday September 22, 2021 @10:55PM (#28624786)
What resources would you recommend for someone new to Phoenix, LiveView, Elixir to get started on this stack?
Re:How we got to LiveView by mrkurt on Wednesday September 22, 2021 @11:06PM (#28624840)
This is a pretty good liveview tutorial: https://github.com/dwyl/phoenix-liveview-counter-tutorial

We also have a hiring project that's designed to ease people in to Phoenix + LiveView. We extracted this from a real app and tried to make it as simple as possible to work on: https://github.com/fly-hiring/phoenix-full-stack-work-sample

Re:How we got to LiveView by iudqnolq on Wednesday September 22, 2021 @11:48PM (#28625022)
What sort of experience level are you hiring for? I've been teaching myself elixir and liveview over the past year for my first job (building dashboards for a non-technical nonprofit) and I've been hoping to transition to working somewhere technical but I have no idea how to do it. Thanks!
Re:How we got to LiveView by mrkurt on Thursday September 23, 2021 @12:10AM (#28625138)
Your experience level, actually. Here's the full post:

https://fly.io/blog/fly-io-is-hiring-full-stack-developers/

Re:How we got to LiveView by iudqnolq on Thursday September 23, 2021 @12:13AM (#28625148)
Thank you!
Re:How we got to LiveView by rishav_sharan on Thursday September 23, 2021 @03:58AM (#28626421)
One question here; is there anything special about Elixir/Beam which makes Liveview on Phoenix a great fit?

Or can LiveViews be done on more performant languages like Go, Rust etc? I am just surprised why we don't see more LiveView implementations in other languages?

Re:How we got to LiveView by neillyons on Thursday September 23, 2021 @06:22AM (#28627327)
Laravel has LiveWire https://laravel-livewire.com which works in a similar way.
Re:How we got to LiveView by Traubenfuchs on Thursday September 23, 2021 @04:45AM (#28626699)
> I am just surprised why we don't see more X implementations in other languages?

X probably doesn't have the mainstream appeal some people think it should have.

Re:How we got to LiveView by chrismccord on Thursday September 23, 2021 @09:16AM (#28628639)
There has been a large number of LiveView-like solutions pop up that are inspired by what we're doing. I tried to outline what makes Elixir uniquely suited to handle this kind of thing in the post, but I'll try to distill it here:

1. The concurrency and distribution model. Processes (light weight green threads) and extremely cheap, isolated, and concurrent. Process can message each other, and messaging is location transparent. So you can send a message to another process on another Elixir server using the exact same primitives as sending a message to a process on the local server. This allows for all kinds of things that are hard or not reasonably possible in other platforms:

- Start a process on a node in us-east1, and message it from Tokyo. This is simply built-in.

- Run a primary DB in us-east1, and RPC from your Tokyo instances to perform writes. The RPC mechanism is again built in. You have code running on another node, and you simply run your code over there and get the result. There's no marshaling of data structures, deploying message queues, protocol buffers, etc

- Using Phoenix Pubsub, broadcast a message from anywhere in the cluster, `PubSub.broadcat(:my_pub, {:new_msg, "hi!})` and it will arrive to all instances who are subscribed, anywhere

This kind of stuff can be made to work well in Go and Rust, but you need to bring in libraries and do more work. They are absolutely great at "network programs", but lacking the distribution primitives means libraries and solutions are usually more bespoke vs Elixir where everyone in the community simply uses what is provided out of the box. So there is no interplay of ops or dependencies to try to reconcile.

2. Processes support stateful applications. Most of the LiveView-like solutions still go over stateless HTTP because websockets and cheap concurrency aren't as viable. This drastically limits what you can do efficiency wise. For example, our diffing engine requires state to live on the server so we know what changed. If you simulate LiveView over HTTP by sending all the state from the client for every interaction, you are sending way more data, doing all the HTTP authentication, fetching the world, then sending the entire template back.

3. Process are preemptively scheduled and load-balanced on IO and CPU. This allows your LiveViews to perform blocking CPU bound work and the scheduler will make sure every other user gets their fair time share. In other languages like Node where you rely on evented IO, any CPU bound work blocks the entire program.

4. Processes are isolated. On the evented IO example, imagine your websocket handler in Node.js has an uncaught exception caused by a single user interaction. It brings down the connections for all connected users. In Elixir, all processes are isolated, garbage collected in isolation, so you aren't jumping thru hoops to handle these kinds of degradation modes.

Hope that helps!

Re:How we got to LiveView by midrus on Friday September 24, 2021 @10:38AM (#28643028)
I really appreciate the work and innovation you are doing, but these other alternatives exist because not everyone is starting a project from scratch, not everyone is able to rewrite their project, and not everyone is building a team with the required skills from scratch.

At a previous company I worked for, a decision was made to move to other platforms not because Elixir was bad, or LiveView was bad (it was good!) but because it was really difficult to hire for.

It is difficult to find people with elixir experience, and we didn't want to have production system built by just people learning a language, platform and architecture on the fly.

Also, that's considering "backend" developers. It was *TOTALLY* impossible to hire frontend developers wanting to work in this setup. No single frontend developer wanted to learn Elixir, and all the backend related stuff. This doesn't happen for example with Node... yes, it might be a terrible choice for the backend, but most frontend devs are happy to work with it.

Regarding to the solutions in other platforms not having the Erlang VM to power them, etc,etc.... not everyone is at google/twitter/facebook scale, 90% of companies out there can be run perfectly fine with run of the mill django/rails/laravel setup.

Premature optimization is as bad when doing an unnecessary SPA as it is using the Erlang VM when rails was enough.

Re:How we got to LiveView by 1_player on Wednesday September 22, 2021 @05:16PM (#28621929)
Phoenix 1.6 has been in alpha/release candidate for a few weeks now. Just curious, what issues are blocking the stable release of 1.6.0? I've checked GitHub but I haven't found any major outstanding bugs waiting to be ironed out.
Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @07:53PM (#28623562)
No blockers. We're simply giving folks time to try things out and report issues. No show stoppers at the moment so I imagine final release won't be far off!
Re:How we got to LiveView by skybrian on Wednesday September 22, 2021 @07:30PM (#28623377)
I'm wondering how this framework handles user feedback for network errors and delays?

It seems like your changes aren't really committed until they hit the database, but there are a lot of intermediate states.

Re:How we got to LiveView by chrismccord on Wednesday September 22, 2021 @11:39PM (#28624980)
We have optimistic UI features where we'll apply a css class to the interacted element, lock that DOM container for inbound updates, and only remove the class when that specific interaction is acknowledged by the server. We can also swap text in a similar fashion. The DockYard blog I linked up thread covers these things in detail.
Re:How we got to LiveView by bugmen0t on Thursday September 23, 2021 @03:51AM (#28626380)
HEEx looks awesome. How does compilation work? Does it properly & contextually encode/escape to avoid XSS? I'd love to learn more about the inner workings.