-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LiveView support #228
Comments
So is LiveView sending a full new version of view as an update, and then it's diffed/patched on the client? |
@Krzysztof-Cieslak, from what I can tell, LiveView does a diff on the server-side by diffing the components that changed, as well as on the client-side, so it always sends the minimal amount of rendered HTML and makes the minimal amount of DOM patches, as well. It seems quite clever. My idea for a first pass was to do something a bit more like Turbolinks and have morphdom do the diff/patch on the client side alone. I don't think the Giraffe view engine is all the way there for defining components and doing diffs, but I doubt that would be difficult to add, either. I was initially thinking of doing something a bit more like Turbolinks but exclusively with a Service Worker when I remembered LiveView. (Actually, reading through the morphdom README reminded me of LiveView). |
I've been curious about how this stuff works so I dug in. Here are some notes from both watching a relevant presentation as well as looking into the client-side library: Presentation: https://www.youtube.com/watch?v=9eOo8hSbMAc LiveEExTemplates are compiled to a list of static components (string literals) and dynamic components (variables)
Iteration elements have optimization for iteration elements (lists). It isn't explained a ton, but I'm guessing it's so that a mere append would only update a singular html element rather than re-render the whole list. I'm sure there are more optimizations you could do depending on what kind of things you send to the client (sets could use an optimization around set differences, etc). DOM stuffContainer div (can be any element) that maintains state for both the front and back ends. Example straight from the talk: <div
id="phx-xeR6nJ8t"
data-phx-session="SQyY.g3QACZAN8XasAQ.RnkD"
data-phx-view="MyAppWev.ClockLive">
<!-- rendered LiveView Template -->
</div>
|
Thanks for looking into this, @Banashek! A lot of this still reminds me of the Blazor Server hosting model, with the biggest exception being the diff on the server-side. @baronfel, you mentioned on Twitter that Blazor had "heaviness." Could you share what you mean by that? While I think a better tie into Giraffe View Engine would be nice, I wonder if it would be possible to set something up like this quickly with Blazor. Another quick, initial implementation might be to avoid the LiveEE template bit at first and just send the pre-rendered HTML via web socket to the client and have morphdom make the adjustment. Thoughts? |
I believe I was thinking along one of two axes:
|
I agree that the initial stage may be done using GiraffeViewEngine (extended with event handlers), rendered on the server and pushed through channels (from server to client), with event handlers communication also going through channels (from client to server). |
An alternate approach that sounds close-ish to the "initial stage" you're describing: https://github.com/hopsoft/stimulus_reflex Essentially turbolinks, except websockets + stimulusjs. Only adding the link to increase the sources for inspiration. Also, While I've done some investigation into websocket performance (and memory requirements) in dotnet core, I'm curious as to the overhead of having sockets open per client, especially when you think about how liveview will open multiple channels for each top-level live-component. Definitely premature optimization at this point, but something to note regardless. |
So I think I have some understanding how to design and implement initial version... but for a moment I want to take a step back and ask the question - when you'd use it over Elmish/React/Whatever on the client? Is that just about, oh I don't want to use stupid JS frameworks or do we have any use cases where it's just better than "normal" client-side rendering. |
The server-side diffing sounds related to what @krauthaufen and @dsyme are investigating with https://github.com/fsprojects/FSharp.Data.Adaptive |
I would tend to use it when you would find a client side framework overkill but you would like to improve the response time from an otherwise server-side app. |
This approach allows end-to-end diffing through a programming model (it probably also allows carving off a fully static part too by enforcing the use of applicatives for the static slice). However it is quite invasive on the programming model itself - I wrote up a prototype of what it would mean to add this to Fabulous here: fabulous-dev/Fabulous#258 (comment). In practice recovering the diff may be simpler - I'm still undecided if it's better in the long run to limit MVU to the simple cases (recover the diff but harder to scale to massively data-rich UIs) or complicate MVU views by using things like FSharp.Data.Adaptive, but get end-to-end diffing. |
Just putting this out here for folks to evaluate. |
Phoenix LiveView (announcement) leverages the channels mechanism to provide real-time updates to server-rendered content in web applications. In my opinion, this is one of the best parts of Phoenix.
For those unfamiliar with LiveView, here's a quick synopsis from the README:
LiveView reduces the overhead of JavaScript client-side frameworks and libraries, aside from a DOM diff/patch tool like morphdom.
With channels seemingly well underway, might it be time to add LiveView support either in the core as a library? I started this issue following this Twitter thread. I would be happy to work on this or help out in some way.
The text was updated successfully, but these errors were encountered: