Phoenix LiveView Info

Looks awesome - can’t wait!

Nice to see error and reconnection handled…

One thing I worry about is outdated js/html running against updated server code - eg my 3 day old tab which now has outdated js/html, or a just deployed release when I’m still connected, and gets reconnected to “new” code that may contain changes - maybe need a manual min_version constant that one can set and if the client is too old phx-must-reload event happen, or something…

but I may just be overthinking it…

1 Like

@chrismccord
What if someone is developing a Facebook style chat and notification system through Phoenix LiveView?
I think the chatbox will be erased and re-created with every new page visit, the websocket connection will break and a new websocket connection will establish, so it will be heavy on the server, especially when there are so many users connected at a time.
Am I right or I am missing something?

1 Like

Depending on how liveview initializes it might be possible to combine it with something like barbajs/pjax or turbolinks to keep parts of a page alive while changing other parts out.

@chrismccord I‘m wondering if there are ways to make this even more fail safe by implementing a way to (optionally) have plain http requests trigger the same kind of action a phx-click does execute. This way one could treat a live view as progressive enhancement, where e.g. the temperature controls in your post would still work even if the whole js fails.

That sounds like just not using LiveView though… ^.^;

1 Like

Before we explore the push state ideas, you are right that LiveView would not be ideal for that use case, depending on your app. If we ignore the need for transitions with pushstate, for example your app doesn’t use unique URLs for the navigable “pages”, then your chatbox isn’t asn issue, since a LiveView can conditionally render the “page” based on the view navigation state. For example, the snake game uses that approach to render the Game Over screen vs active game template: https://gist.github.com/chrismccord/60a5705482d26326675c7b752ed0dacd#file-snake_view-ex-L47-L57

You are right that if you need actual page navigation with a persistent chat box, LiveView as it will exist for 0.1 won’t fit your needs. One of our goals as we continue feature development with LiveView is to find the limits. I think we can absolutely make it work well for a chat application, but embedding a chat within an otherwise navigable site will need exploration. @LostKobrakai is right that if you wired up a pjax approach, the chatbox would probably Just Work, but you’d need to be careful about how you nested the LiveViews to make that happen.

2 Likes

Fallback to regular form POST’s is not in my plans, but you could roll it yourself by implementing the routes and controllers for your phx-* forms. It would still be limited because you lack any state on the controller side, but you could use it to broadcast messages for other, realtime users. I’m okay saying we require JavaScript for interaction (but not initial render!, ++SEO :)). The neat thing is if you had a <noscript>Sorry JS required please</noscript> in your LiveView, it would only ever be sent a single time, and never again on any update :slight_smile:

So @chrismccord, just for clarity, let’s say I have a video hosting platform and on a video playback page, I have a few tabs that users could click.

Clicking a tab changes the content below the video without the video being interrupted. It also happens to adjust the URL by adding /notes or /downloads to the end, based on which tab you’ve clicked.

Right now I’m doing this with ajax calls where on link click, it loads the content under the video in the tab’s container. Are you saying with LiveView 0.1 this won’t be possible because the URL state wouldn’t be tracked?

Would LiveView even be a good fit for that even if URL state was saved? Some of the tabs can have a lot of HTML content (think 10kb of HTML, since it would be almost a blog post that loads from the request).

That would just be all around a ton easier with Unpoly.js for note. :slight_smile:

1 Like

Yeah right now I’m using manually wired up ajax calls, and it’s not scalable at all (not performance related, it’s just a lot of boilerplate for each one – there’s 4 tabs). I wouldn’t mind pulling in a lib to help with that but only as a last resort.

There’s other components of this app that would fare very well with LiveView (form validations, toggling completion states on videos, autocomplete search).

Throwing this in as something for (way beyond?) 0.1. We will need/want

  • we need an ability to define delay/throttle on phx- events

  • a way to hook into LiveView: send phx- events from JS, introspect/modify/monitor incoming and outgoing data, “lifecycle hooks” (on connect, on send, on error, on close etc.)

  • previous bullet point can probably help with maintaining state between URL changes

So far, even if 0.1 only allows you to manipulate one single page, it’s already beyond awesome, and can be battle tested to find the limitations and further needs.

1 Like

Unpoly can handle all of that as well too by asking the server about it all or basing things on events that happen (all server controlled). ^.^
I highly recommend it.

1 Like

debouncing will be part of the initial release for the delay/throttling of events

7 Likes

@chrismccord, 2 questions:

  1. Any plans for a LiveView linter (so that not everything appears green)? Would be nice to have.

  2. One place where React struggles is when one wants an event in a child component to “bubble up” to its parent. Basically, one needs to pass an action function (with a captured reference to the parent’s state).

    Alternatively, one can use Phoenix Channels (using channel events for actions–instead of REST–and setting channel event listeners throughout one’s component hierarchy, which can each modify their respective state in a unique way).

    Now with Phoenix LiveView, a new possibility is introduced: component message-passing.

    Because each component’s state is really just a process with some event handlers, if something happens in one component, just as it can send itself an event (as in your blog post’s examples), it could send an event to another component’s state process.

    In order to make these processes accessible, it would be easiest to register each with a name.

    Is that possible, and WDYT of this potential design pattern?

2 Likes

Do you mean for syntax highlighting? That would be editor dependent. Here’s my emacs highlighting with mmm-mode:

generic html.leex files are also supported like any other html.eex file.

wrt to messaging passing, you can use registry with the view’s unique ID to messaging b/w parent and children views. We don’t register them by default, but it would be a couple LOC to do it yourself. We’re going to wait a bit with messaging since it’s not clear what the best approach is. For example, ad-hoc messaging b/w react components is known to scale poorly architecture wise, but LiveView’s will likely be less complex so it may be fine.

5 Likes

Do you know of any open source examples that use Unpoly? It’s a pretty big library, but there’s really not too many tutorials written on their official site.

I wonder if there’s a way to only pull in a tiny aspect of it, although going by their docs, I’m not even sure what aspect I would use to pull in ajax content. I guess ajax.accel, but it’s also tagged as experimental.

I started working on a lightweight lib to do what LiveView does except without a dependency on Pheonix, because simply cannot wait for LiveView code to be posted to github, if anyone interested check it out https://github.com/vans163/morphling (forum thread)

ATM I wanna ask how LiveView does the DOM diffing on the server side? Its actually quite challenging to figure out how to send the differential between 2 binaries.

2 Likes

What tutorials are you needing? Unpoly.js is very piecemeal, only use what you need, and all the features have great documentation. If any of the documentation is lacking then I’d assume telling them on their github repo would be best, but I’ve never had an issue with the documentation as it seems quite comprehensive?

It’s an older style library sadly, not built using modern modules, though it looks like they are slowly moving that way.

I can’t find any information on the ~L sigil used here. Is this LiveView-specific? Where does it come from and what does it do?

Right, I wouldn’t want to bring in a 109kb library (the minified unpoly JS size on github) just for a few ajax calls since I imagine most of my other things (like video progress tracking, search autocomplete, etc.) could be done with liveview?

1 Like

Sounds like you are a usecase to make PR’s to them. ^.^