First 10 of 22 Posts Switch mode

thiagomajesk

thiagomajesk

To me at least, it seems like it’s a little bit more streamlined than LiveView right now.
Also, with more “moving parts” to use with different workflows - while LiveView is very opinionated.

I’d say it’s more like a combination of Alpine (Stimulus), Unpoly (Turbo) and LiveView (Hotwire).
IMHO, the seemless integration between those worflows is the big deal (aparently).

mgibowski

mgibowski

Here are my first impressions regarding the differences.

What’s good about hotwire is the upcoming Strada with some support for offline mode even if it’s HTML generated on the server-side. I expect it because I see this in the hey app on my iPhone.

What’s good about LiveView - super fast synchronous tests.

Surely there are many other consequences of using one or another. To me LV feels better from the Developer Experience perspective and I would choose this approach whenever I don’t need any offline-mode capabilities.

josevalim

josevalim

Creator of Elixir

Although both are “HTML over the wire”, LiveView is stateful and Hotwire (as well as React Server Components) are stateless.

This is an important distinction and there is a lot we could discuss under this subject but in a nutshell, stateful allows you to decrease latency because each request/event is immediately handled by the connected socket. On stateless, each request has to parse HTTP headers, do authentication, authorization, load data from the DB, etc.

LiveView builds on top of stateful connections to provide a more complete dev experience. Live form validation? Check. Dashboards? Check. File upload? Check. Drag and drop? Coming soon. This is also why people can build games with LiveView, even though it is not its purpose. The downside of stateful though is higher footprint cost on the server but that’s not fundamentally problematic in Elixir because connections are generally very cheap.

Back on the latency side of things, LiveView also does a lot to reduce the payload sent over the wire. When you update a page/frame/component, we only sent what changed. If you add new instances of a component and the component is already on the page, we send only the dynamic bits. React Server Components seem to do the same but I believe Hotwire does not.

We will have to wait for a bit to see how these differences will translate to programming models in the long term and how some ideas will cross-pollinate. You can always reproduce stateless with a stateful model though by discarding all state after every event.

Yeah, Strada was the part I was most curious about. My guess is the offline mode is managed by the frame-specific caches kept on the client (and not Strada). I expect Strada to rather allow you to replace some specific components/frames by native components (that would go alongside the webview). But I am guessing. :slight_smile:

EDIT Feb/2024: since this message is still references from other places, I should add one important clarification. LiveView and Hotwire ultimately are two different programming models: LiveView is declarative, Hotwire is imperative. What this means is that, in LiveView, you don’t say “when someone clicks this, update this frame or render a stream to update this ID”. In LiveView, you simply change your LiveView state and LiveView re-renders the page. The declarative model requires less from the developer and it comes with the major benefit that, by letting LiveView be the one that does the rendering and patching, it can understand your code and apply a lot of optimizations.

37
Post #3
cnck1387

cnck1387

What I find the most interesting about Hotwire so far is Turbo Drive and Turbo Frames allowing you to do body swap page transitions and partial page updates over HTTP with no state or persistent connection on the server and it’s also back-end agnostic, meaning it either requires having to do nothing or very little to make this stuff work with any web framework.

Doing body swap transitions (what Turbolinks 5 did before Turbo Drive existed) makes a huge improvement for perceive page load speeds. The Frames add-on is just icing on the cake to be able to make partial updates to only 1 area of the page. changelog.com uses Turbolinks 5 on their site with Phoenix btw, to give you an idea of what fast body transitions feel like in practice.

I know LV can do this too, but it’s all done over a persistent websocket connection, and the diff of the content is sent over websockets. I know there’s the long polling transport layer but that’s mostly just a worse version of websockets and still requires keeping connections open on the server.

The neat thing about Turbo Streams (also part of Hotwire) is when you do want to do broadcast style events, like having the server push new content to the client or all connected clients you can do that and only pages that use this behavior will keep an active websocket connection open.

I know LV isn’t slow and I’m not worried about keeping connections open on the server with Elixir, but I do not like the user experience this gives when you need to keep a connection open all the time on every page just to do things like fast page transitions.

What’s really interesting in the end is, I think it would be quite possible to build in support for Turbo Streams in other web frameworks too, and Elixir is well equipped to deal with this. The Rails implementation is extracted out in a gem at GitHub - hotwired/turbo-rails: Use Turbo in your Ruby on Rails app · GitHub. That includes convenience Rails helpers for Drive and Frames too but the bulk of it is for Streams.

I wonder if we’ll see a community driven LV alternative using Hotwire, or if LV will take inspiration from the good parts from Hotwire.

josevalim

josevalim

Creator of Elixir

Agreed on Turbo Drive. I consider it to be completely orthogonal to LiveView though and people can and have been using unpoly or turbolinks to achieve the same behaviour - as you mentioned.

However I am not convinced about turboframes.

The way turboframes seem to work is that it renders the whole page and then just plucks out the frame. At the moment I don’t know if the frame is being plucked on the server or on the client, but because frames are also meant to be functional when accessed directly via the browser, you are still doing all of the work necessary to render the whole page (parsing request, auth, authz, loading all data, etc) only to get a tiny bit from it.

And if you get the same frame multiple times, you are loading the whole frame markup multiple times. I can see how someone could optimize turbostream to introduce some bookkeeping and avoid this repetition but I am really struggling to visualize how anyone would optimize the frames.

When LV was released, most of the questions were how to reduce work done on the server and the amount of data sent over the wire, so I am curious if hotwire is going to be held to the same level of scrutiny.

EDIT: another area where you probably need a stateful connection is live form validation. Otherwise, if you are doing complete requests over a frame to live validate a form, I don’t believe it will be responsive enough.

derek-zhou

derek-zhou

Fully agreed. You don’t even need turbolink if you just want to swap pages or part of a page. Just make views that render to html snippets and let the client side load them via fetch(). People do that all the time. If you need to use websocket you may as well do one step further and make the whole thing stateful like LV.

LostKobrakai

LostKobrakai

To be honest this sounds a bit like “you don’t need phoenix to serve a website. Just serve some html with cowboy.”. The problem often isn’t the fact that things are not possible, but not having a good abstraction to deal with a whole manner of problems with the same blueprint. Those do allow for greater efficiency and less one-off ways of dealing with problems.

derek-zhou

derek-zhou

It is all about the bang for the buck. I for one welcome a Basecamp backed, standard way to do stateless partial page updates in HTML. The people over there has great taste.

cnck1387

cnck1387

I don’t know it well enough to answer this question with certainty but I’m pretty sure DHH mentioned this in the video. If you access a frame for a 2nd time and the content didn’t change the server will respond with a 304 content not modified and you can use the cached version.

I suppose that’s one benefit of using HTTP for certain things. You get access to 20+ years worth of optimizations and standards.

I’m not sure if it will right away because most of it is stateless, it’s just HTTP requests all the way down. It was stuff that your web server was doing anyways, and now with frames you only have to return snippets of HTML (let’s say the HTML required to render a new tweet card’s details) instead of the entire page body, so it’s a net win vs the previous implementation. Combine that with caching, and it doesn’t seem like the end of the world to be less strict with bytes over the wire.

But, of course less bytes over the wire is good. Maybe a future version will do dom diffing.

Although after looking at some examples, sometimes not diffing ends up being a feature to write less code. For example image a tweet card being updated. With LV you would need to wire up multiple events to edit the tweet, handle likes, etc.. That’s because each surgical update is totally isolated.

But with frames, you would wrap the whole card, write 1 controller endpoint and you’re done. If it ends up updating 1 attribute or 5 attributes that change you only ever have to wire up that 1 thing.

I guess that leads to progressive enhancement too. Since it’s just a controller being rendered without a layout and other cruft when Turbo Streams kicks in, it falls back to a full page load when websockets aren’t available. It’s a bit harder to pull that off in LV without lots of duplication right? Making both LVs and controllers, etc.

It’s too soon to say which approach is better overall but I think there’s definitely pros and cons to both Hotwire Turbo and LV.

chrismccord

chrismccord

Creator of Phoenix

This isn’t quite right. On broadcast side, your system can broadcast a generic “Tweet Updated” event, and then LiveView will surgically send the diffs based on what changed without any work for the dev – rt count, likes, body, etc. For the write side, setting up a single endpoint for the tweet update isn’t accurate in this case either, because you will likely have a RT endpoint, a like endpoint, an general edit endpoint, etc. In general, some things can be handled by a generic update of params, but atomic updates such as likes/rts that involve specific actions like notifications are necessarily going to require specialized handling, so you are writing your events in LV or inside multiple controller code paths, the latter of which requires extra routes and handling vs LV.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 91561 914
New
byu
@chrismccord : I just saw the Extract AGENTS.md from Phoenix.new into phx.new generator commit to the phoenix project. My initial shotgu...
New
arcanemachine
I was working on an Ecto migration and I needed a timestamp. So, for the nth time, I looked up the different data types for timestamps, a...
New
AstonJ
Just a general thread to post chat/news/info relating to AI/ML stuff that may be relevant for Nx now or in the future. Got anything to sh...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
alexslade
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog It says that Fly is going all-in on sprites, which is a worry ...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
akoutmos
@hugobarauna and I (Alex Koutmos) have been hard at work on writing a book on Nerves that takes you from simply blinking LEDs to building...
New
mudasobwa
While I am working on the Language Agnostic Code Audit SaaS, which uses MetaAST (spoiler: I am expecting it to be in a good shape for ann...
New

We're in Beta

About us Mission Statement