Now that we have LiveViews, is there a use case for regular Views?

Hi all,

I’m still making my way into the Elixir/Phoenix world and have been developing a proof of concept to cut my teeth on. I just recently started using LiveViews. I’ve been working with regular Views thinking that would be an easier introduction to the framework, but then I got curious.

As I’ve been working with LiveViews, I’ve begun to wonder: is there still a use case for a regular View now? This is a sincere question. For my proof of concept, it doesn’t seem to make sense to have the two types co-existing, at least as far as I can see at this point.

I would honestly appreciate anyone’s perspective on this because I have it half in me to convert all my regular Views to LiveViews because it’s likely that I’m missing something or cannot see far into the future due to my my lack of experience. :innocent:

Would like to hear perpsectives on:

  1. When would it make sense to keep a mixture of regular Views and LiveViews?
  2. When would it make sense to use only regular Views?

Cheers!

The first thing that comes to mind would be your target audience is not guaranteed to have a stable internet connection. In this case, if you had a JS/WASM based SPA, you could potentially still have access to some functionality of the application while the user is offline.

2 Likes

The example comes to my mind:
Suppose we have a very large of data to render in html, and we don’t want to “assemble” in memory and render at once. We could leverage http/1.1 chunks or http/2 streaming from within regular controller with Plug.Conn.send_chunked/2

However, we could probably just stream that same huge amount of data through WebSockets with LiveView =)

I remember in one of the recent ElixirConfs someone asked similar question to Chris McCord on which he jokingly answered “dead views are dead to me” =)
(worth to mention, that he also said that “regular views” are not going anywhere)

1 Like

If Javascript is disabled on the client computers, liveview won’t work. If you need to render pages without any interaction, it might be better to use regular views since they will send the data only one time but liveview will send the data 2 times when it calls mount (first time: regular HTML, second time: static HTML + dynamic data + Javascript).

1 Like

From an technical pov it‘s worth mentioning that those two are not separate systems. LiveView uses the existing Phoenix.View related tooling. The only thing it brings new to the table is the .leex templating engine.
Co-located templates are a convenience, but liveview started like with controllers where you‘d need separate view modules for the actual templates. As soon as you want to import template partials you still need that today.

1 Like

Plus the lifecycle management - a persistent process on the server maintaining a single source of truth for state (and able to push changes to the client) rather than re-creating state for each request / response cycle is a huge win for performance and management of incidental complexity.

To the OP’s question…

Since LiveView was released as an early alpha the only non-LiveView code I have written is:

  1. Initial authentication (it can probably be moved over now)
  2. Some navigation bits (again, can probably be moved now)
  3. JSON APIs
  4. File upload end-points (waiting for the release of file uploads) - the file upload form was rendered in LiveView
  5. Static asset serving (e.g. images), but that’s not going through the Phoenix view-controller plumbing anyway

I think we’re at the point where my choice would be 1) LiveView or 2) JS hitting Phoenix APIs or 3) JS interacting with LiveView plumbing (i.e. pushEvent/handleEvent), and most likely a combo of 1 for most pages and 3 for the heavily used/highly responsive/highly graphical functionality.

1 Like

True, but that has imo nothing to do with views or templating, even if .leex is what makes it possible.

1 Like

Ah - I think we read the question differently - I see what you mean now. Hopefully what the OP thought the question was has been answered one way or another!!

1 Like

Thanks @Ankhers @RudManusachi @imartinat @LostKobrakai (love the name) @mindok for your responses.

@RudManusachi thanks for sharing about send_chunked. I’m still learning about the framework so I found your share to be a little gem to keep in mind for future. Also, curious what Chris really meant by dead views if he stated regular views aren’t going anwyhere. Do you know?

@mindok appreciated reading about your journey so far and how you might move forward.

@LostKobrakai thanks for bringing that to light. It shined some light on a possible solution to what @Ankhers and @imartinat have raised, which is what I’ve also heard from people in Discord (e.g., connectivity, latency, etc.). Since the two are not separate systems, then is it possible to fallback to regular views? How could we go about developing defensively with LiveViews in case they fail? Is that in the Phoenix framework or would it be a handrolled solution that we would need to write for ourselves?

I had pretty much the same question and thought process as you not too long ago.

I ended up coding up a bunch of my app without live view, then an entire LV version of it and then I ran into show stopping issues around LV and called off the LV version.

I could see going full LV one day but it’s still pretty rough around the edges IMO. However, if your app is very simple it’s worth a try.

4 Likes

Wow. Interesting! What did you end up doing? Back to regular views and mix in React.js or some equivalent?

I stuck with what I know, which for me was Turbolinks and a sprinkling of ES6 JS. No dedicated SPA front-end and the back-end stays the same as usual.

The really cool thing is the next version of Turbolinks (should be out in a 4-6 weeks or less) will support partial page updates. Basically the technology currently running https://hey.com. A web email client that feels like a single page app but uses server rendered templates and a little bit of JS here and there.

In the above case they also use StimulusJS to organize their JS, but that’s an implementation detail that could be swapped out for Alpine, Vue, jQuery or whatever you’re comfortable with.

2 Likes

That’s interesting – Turbolinks. The reason I looked into LiveView was because I wanted to use the Phoenix version of Turbolinks for Rails. I considered using Turbolinks, but I thought it would be safer/better to use what comes in the Phoenix “box” so to speak. Hmm… definitely some food for thought. Thanks for sharing! Curious, how has Turbolinks and Phoenix worked together for you? Have you had any issues?

It works flawlessly for GETs without needing any server side changes, and if you want to handle form submissions you can drop in this Phoenix Plug https://github.com/thechangelog/changelog.com/blob/master/lib/changelog_web/plugs/turbolinks.ex and you’re good to go.

https://changelog.com/ is built with regular views and Turbolinks btw and it’s all open source.

Also, Turbolinks 6 will be fully client side, even for form submissions because Fetch’s API knows what to do with redirects. Whenever that drops, then supposedly that Plug will no longer be needed. I say supposedly because I’m not a developer working at Basecamp, I’ve only been following what they’ve publicly wrote on Twitter and I looked at their JS source maps of Hey.

2 Likes

I would highly recommend https://unpoly.com/ which is what we use for our non-liveview Phoenix app. It’s like Turbolinks but includes many enhancements such as partial updates, handling redirects and even support opening responses in modals/popovers — essentially 90% of what you need to make a regular server side rendered app more responsive and interactive. All without any changes to the backend at all (although you could make serverside enhancements for optimization reasons).

5 Likes

Awesome! Thanks for sharing. I’ll check it out!

I hope they update turbolink soon and add more functionalities. I still use turbolink for simple or static sites, however for anything more sophisticated I feel it is not worth the 50KB javascript size. After all, you can implement background loading yourself with < 100 line of vanilla ES6 with some small amount of cooperation from the server side.