[HN Gopher] How We Got to LiveView
___________________________________________________________________
How We Got to LiveView
Author : klohto
Score : 264 points
Date : 2021-09-22 19:14 UTC (3 hours ago)
(HTM) web link (fly.io)
(TXT) w3m dump (fly.io)
| heeton wrote:
| Personal anecdote: LiveView is absurd. It's the biggest change
| I've experienced in web development since Rails v1.
|
| I've been able to build rich, interactive, _games_ without a
| single line of Javascript. It takes complicated server / api /
| front-end build projects and results in literally 1/10th the
| amount of code for the same result.
|
| It's one of the few times in our world that the technology isn't
| just "new and cool" but "fundamentally better".
| rvense wrote:
| I really wanted to use it at my last job, where we had a Go
| backend and a React SPA and a sprawling, ad hoc RESTish API in
| between that was only used by the SPA.
|
| We were mostly split between Reactors and Gophers, and the
| amount of time we spent arguing about the API and implementing
| it... I'd say was easily one third of the word, if not more,
| that would have just gone away if we didn't have to worry about
| the details of the data we were moving back and forth.
|
| My current job is a bit too front-end heavy for LiveView to
| make sense. But I still keep an eye on Phoenix. It really feels
| like it could be a secret weapon, at least until every one else
| adopts a similar pattern.
| dugmartin wrote:
| I've used LiveView as it was meant to be used in a couple of
| small personal projects but in my latest (much larger) project
| I'm using it in a way that (given what I just read in this post)
| would make Chris' head spin.
|
| Basically I'm using it as a container wrapper for a large React
| app and keeping all the state on the client. This is only for the
| app pages on the site, the rest of the pages are either
| traditional "deadviews" or LiveViews.
|
| Why?
|
| 1. I have a lot of state. Its an accounting app and I want the UI
| to be zippy. Because I don't want to keep all that state on the
| server (per user connection) I would have to use temporary
| assigns to keep the server state small which means lots of
| queries and data shipping when searching/reordering/generating
| reports. Nothing beats only shipping the data once over the wire.
| And I do know about all the hacks to update local lists using
| components - that doesn't help when I need to use/display the
| same data in different ways.
|
| 2. While I love the expressiveness of Elixir the lack of a type
| system makes UI development/refactoring much slower for me as
| opposed to React+TypeScript. Note: I have several years
| experience in both Elixir and React+TypeScript over many projects
| so I don't come to this conclusion lightly.
|
| 3. Using LiveView is much nicer than using Channels since I can
| delegate common elements of the page to it instead of replicating
| it in React. Sort of a Russian nesting doll of rendering. Plus
| the LiveView is colocated with the other pages in the site which
| makes it more tidy.
|
| 4. I don't have to write an API - its just LiveView messages.
|
| 5. I don't care about SEO for the app pages (and explicitly don't
| want it indexed).
|
| 6. I'm using Elixir/Phoenix/Ecto for its best parts - supporting
| lots of websocket connections and hosting the core logic (and the
| non-app pages). I shudder at the thought of running a fleet of
| node apps to do the same.
|
| I'm not sure why I wrote this other than to let folks know that
| LiveView can be used in ways that might not be obvious from an
| initial look.
| vosper wrote:
| > HTTP almost entirely falls away. No more REST. No more JSON. No
| GraphQL APIs, controllers, serializers, or resolvers
|
| In React / Typescript world you can get a little bit of this with
| Blitz - but not the live updating part, as far as I know. I found
| there was quite a lot to learn, but I'd also been out of the
| React world for a couple of years. Probably getting up to speed
| with TS was half of it, and obviously that's not due to Blitz.
|
| It has felt quite magical thinking only about the DB and React,
| and so far it's just worked.
|
| "Blitz is a batteries-included framework that's inspired by Ruby
| on Rails, is built on Next.js, and features a "Zero-API" data
| layer abstraction that eliminates the need for REST/GraphQL."
|
| https://blitzjs.com/
| shthrow wrote:
| How is it a good idea for every user interaction to hit the
| server?
| michalg wrote:
| This is not the idea. Interactions that don't influence server-
| side state are suggested to be handled by JavaScript. Docs give
| an example for integrating AlpineJS, but you can use vanilla js
| or other libraries with little plumbing.
| erinan wrote:
| Whether it's a good idea or not really depends on your app,
| what you're trying to do, and who your users are.
|
| Now if you want to avoid round trips to the server for
| interactions such as opening a modal, you can!
|
| There are at least two ways to handle this - Javascript hooks
| that let you attach JS to your DOM, or the light AlpineJS
| framework. The latter is a perfect fit for Liveview and it's
| part of the unofficial go-to stack name PETAL - Phoenix Elixir
| Tailwind AlpineJS Liveview.
| kureikain wrote:
| it helps debugging and avoid any issue with cache(old
| JavaScript, unexpected JS error etc).
| sodapopcan wrote:
| Websockets are crazy fast and the BEAM has crazy fast IO (at
| the expense of slower CPU-bound tasks, but that is another
| story). LiveView also minimizes (to an obsessive degree) the
| amount of data that flows over the socket. The payload is about
| exactly the size as the exact diff being rendered in the DOM
| (often times this is simply the `innerHTML` of a node).
|
| The advantage is stack simplicity. As stated in the beginning
| of the article, LiveView completely removes your need for any
| kind of API between your front and backend. It also makes it
| very easy (through JS hooks) to offload any interactions you
| want to the client if that makes more sense. But of course, if
| you end up offloading EVERY interaction to the client, you
| should be using a frontend framework--LiveView is very clear
| about not being suitable for every need--if you are building a
| super UI heavy app (like a text editor or painting app or the
| like), LiveView probably isn't going to cut it.
| mrkurt wrote:
| A server round trip is a cost. It's not a good idea or a bad
| idea.
|
| I will pay the cost of a round trip if (a) it simplifies my
| life and (b) the cost is low enough. LiveView vastly
| interactive app development (for me). Since I can run my
| Phoenix servers close to people, the round trip cost is usually
| very low.
| chrismccord wrote:
| 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!
| davidw wrote:
| 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?
| innocentoldguy wrote:
| 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.
| scraplab wrote:
| 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.
| modal-soul wrote:
| If LiveView is backed by PubSub, then I think you can offload
| persistence to Redis.
| whitepoplar wrote:
| 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!
| innocentoldguy wrote:
| 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
| mrkurt wrote:
| 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/
| whitepoplar wrote:
| 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.
| mrkurt wrote:
| 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.
| whitepoplar wrote:
| Sounds like customers are in good hands!
| PKop wrote:
| 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)
| tptacek wrote:
| "Non-technical Fly.io founder", who do you think you're
| kidding? You have more commits than me in the last week.
| nightpool wrote:
| 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?
| erinan wrote:
| 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?
| sodapopcan wrote:
| 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]
| staticelf wrote:
| 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?
| losvedir wrote:
| 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?
| ashton314 wrote:
| 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.
| chrismccord wrote:
| 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.
| giancarlostoro wrote:
| 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.
| ashton314 wrote:
| There's been some progress on this front, I believe:
|
| - https://hexdocs.pm/phx_gen_auth/overview.html
| chrismccord wrote:
| 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
| giancarlostoro wrote:
| 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.
| 1_player wrote:
| 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.
| foofoobar wrote:
| 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?
| ketzo wrote:
| 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.
| chrismccord wrote:
| 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
| ignoramous wrote:
| 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.
| jarpineh wrote:
| 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.
| ethnt wrote:
| 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?
| spiderice wrote:
| 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.
| klohto wrote:
| 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 :)
| chrismccord wrote:
| 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...
| chrismccord wrote:
| 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!
| sgrytoyr wrote:
| 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!
| akoutmos wrote:
| 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 :).
| cs44 wrote:
| I'm surprised to see so few mentions of AlpineJS.
| Personally, PETAL has become my de facto stack.
| sodapopcan wrote:
| 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 _micro_ seconds). 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.
| joppy wrote:
| 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.
| sodapopcan wrote:
| 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).
| louissm_it wrote:
| 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.
| chrismccord wrote:
| 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_l
| ive_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...
| sgrytoyr wrote:
| 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.
| mrkurt wrote:
| 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.
| kureikain wrote:
| 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.
| sillysaurusx wrote:
| 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. :)
| Kiro wrote:
| 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.
| sillysaurusx wrote:
| 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.
| Kiro wrote:
| Found it!
|
| https://blog.chriszacharias.com/page-weight-matters
| sillysaurusx wrote:
| 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. :)
| Kiro wrote:
| 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.
| a-dub wrote:
| > 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.
| chrismccord wrote:
| > 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.
| sillysaurusx wrote:
| 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.
| chrismccord wrote:
| 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 :)
| sillysaurusx wrote:
| > 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.
| ignoramous wrote:
| 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).
| yewenjie wrote:
| 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/
| PKop wrote:
| 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
| jherdman wrote:
| 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?
| mrkurt wrote:
| 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.
| turtlebits wrote:
| 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.
| hervature wrote:
| Hey Chris, excellent work. Very excited about 1.6 and LiveView.
| If you update your Programming Phoenix, I would certainly pay
| again.
| tclancy wrote:
| Seconded!
| ashton314 wrote:
| > I created Phoenix to build real-time applications. Before it
| could even render HTML, Phoenix supported real-time messaging. To
| do that, Phoenix provides an abstraction called Channels.
|
| I think it's really neat that Chris started out with real-time
| messaging. When I first started working with web frameworks, it
| definitely felt like real-time stuff was an afterthought--a layer
| built atop an older model that leaked a lot of the details.
|
| Working with LV has been an absolute delight. Need to render a
| PDF and download? Fire off a `Task.async` to render in a separate
| thread on the backend. When it's done, that thread _can just
| `send` a message to the LV process to update the UI that the PDF
| is ready._ So easy and painless. LV really hits a sweet spot for
| me: I 'm primarily a backend dev, but with LV I can build really
| nice stuff on the front-end with minimal effort/headache from
| NPM.
| tptacek wrote:
| This would make a great short blog post.
| sergiotapia wrote:
| I'm leading the engineering effort of a stealth startup in Miami
| and we are using Liveview to power everything. It's very
| liberating. Heex does have it's warts and it is very new so
| expect to do some forum spelunking - but Chris McCord and Jose
| Valim are both very active and care about the product they are
| building. Usually things get fixed quickly. They are the heart
| and soul of the Elixir/Phoenix ecosystem so thanks a bunch for
| all their hard work.
| clone1018 wrote:
| We use Phoenix and LiveView to power all of our non-video
| interactions on Glimesh.tv[0] and the immediate out of the box
| features and performance are unmatched. LiveView allowed us to
| get a completely real time updating channel where streamers can
| edit their metadata (game, title, viewer count, etc) and all of
| the viewers can see it in real time. Not to mention we
| implemented a distributed chat system that sends message updates
| in real time to both browser clients and API clients. Both of
| these features combined amount to less than 1000 lines of code
| and "just work" across multiple web nodes.
|
| It can be daunting to jump into such a strange world as a
| LiveView environment may look (Elixir syntax, OTP terminology,
| etc) but honestly once you dig in deeper, everything just makes
| sense. LiveView (and HEEx) continue to be very simple to
| understand abstractions on top of the rock solid OTP platform.
| It's a joy to build real time applications using it, and I very
| much appreciate the "developer experience" focus both Chris &
| Jose have for us Elixir devs!
|
| I'm excited for the launch of Phoenix 1.6 and HEEx is shaping up
| to be a complete replacement for your traditional SPA + Backend
| API, and using one consistent language for your full stack really
| has very freeing & powerful benefits, especially for small teams!
|
| [0] https://github.com/Glimesh/glimesh.tv/
| nickjj wrote:
| Are you using Live View for everything related to navigation
| too? For example if you transition between any page, is this
| happening through Live View?
|
| In any case, I'd love to chat with you on my podcast on how you
| built and deploy Glimesh if you're interested. It's at
| https://runninginproduction.com/, there's a become a guest
| button in the nav bar on the top right if you wanted to
| schedule a call to be on the show.
| [deleted]
| cgarvis wrote:
| Slight difference from stock phoenix but yes. Only area I'm
| not 100% on is auth.
| https://hexdocs.pm/phoenix_live_view/live-navigation.html
| wmanley wrote:
| This sounds like an optimised implementation of the design
| described in "The Future of Web Software Is HTML-over-
| WebSockets":
|
| https://alistapart.com/article/the-future-of-web-software-is...
|
| HN discussion: https://news.ycombinator.com/item?id=26265999
|
| I find developments in this area very exciting as I'm sick of
| dealing with layers and the required tedious glue you have to
| write to join them together.
| polyrand wrote:
| I have never used LiveView, but I'd love to see the web moving
| towards this kind of interfaces. HTML over the wire is powerful!
| The deep integration between all the parts (Phoenix, LiveView,
| the HEEx engine...) is nice, and compile-time template validation
| looks really cool.
|
| One thing that concerns me about doing everything over
| WebSockets, is that it seems you now need to keep a connection
| with every connected client, even if they are not doing any
| "highly interactive" actions. I think (in most cases) it would be
| more efficient to do a bunch of AJAX requests to receive those
| HTML chunks. Now that we have CDNs, HTTP/{2,3}, etc. the benefits
| of using WebSockets for everything seem less obvious.
|
| This is what HTMX[0] does by default, and then you can use
| WebSockets[1] if you need it. Another great thing about HTMX is
| that the backend can be whatever you like, as long as you can
| handle HTTP requests and return HTML.
|
| In any case, I like both approaches and I would love to see the
| web development ecosystem moving back to sending HTML over the
| wire, regardless of the framework.
|
| [0] https://htmx.org/
|
| [1] https://htmx.org/attributes/hx-ws/
| y4mi wrote:
| Elixir (the language phoenix is written in, which is the
| framework that has these live views) is great with concurrency.
| You can have incredible quantities of parallel sockets open
| with basically no overhead. There have been various write-ups
| about it if you're interested.
| egze wrote:
| Just want to say - thanks Chris! LiveView is the most innovative
| web technology I've seen in the last 5-10 years, and it is an
| absolute joy to use.
| sodapopcan wrote:
| Agreed. I haven't been this excited and motivated by any
| technology since I got into rails 10 years ago. It's been a
| great cure for the jadedness I've been feeling about our field
| in the past couple of years.
| cs44 wrote:
| "Since I got into rails 10 years ago..." -- this is my line!
| Cheers!
| olah_1 wrote:
| Imagine building federated tech with this. ActivityPub stuff like
| Mastodon, Peertube, etc. The performance on small servers would
| be incredible.
| joshuakelly wrote:
| I didn't realize Fly hired Chris McCord. Wow!
| bdcravens wrote:
| > Sync.rb works like this: the browser WebSockets to the server,
| and as Rails models change, templates get re-rendered on the
| server and pushed to the client. HTML rendered from the server
| would sign a tamper-proof subscription into the DOM for clients
| to listen to over WebSockets. The library provides JavaScript for
| the browser to run, but sync.rb programmers don't have to write
| any themselves. All the dynamic behavior is done server-side, in
| Ruby.
|
| It sounds like Stimulus Reflex is essentially Sync v2 (today's
| libraries are able to accomplish Chris's original vision)
|
| https://docs.stimulusreflex.com/
| tptacek wrote:
| I think that's true? More platforms should invest in the "sync"
| vs. "render" abstraction, especially the platforms that have
| strong concurrency already.
|
| A Big Phoenix idea though seems to be that you can take this a
| big step further: now that you're syncing, keep the state that
| you'd be attaching to React components serverside, and let sync
| update the front-end. It feels like a lot of the benefit you'd
| get out of a carefully-designed GraphQL API, but with none of
| the plumbing work.
| tommica wrote:
| I've had such hard time wrapping my head around how to think in
| liveview - I've tried tutorials and building my own projects, but
| always end up thinking "am I doing this the right way"? How do
| other people structure their codebase, and what are the
| considerations they have? I think I'm trying to force my way of
| working with react and laravel, and lack some kind of a
| fundamental way of thinking to get my "aha!" Moment
| sodapopcan wrote:
| I totally get the "Am I doing this the right way?" feeling,
| especially coming from Rails where everything was so
| opinionated and wanting to stay idiomatic.
|
| Phoenix, while it does have opinions, is far less opinionated
| in the sense that it doesn't do its darndest to force you into
| certain conventions (for example, if your module name doesn't
| match your file name, Phoenix won't complain). Its generators
| do try and push you toward using good DDD practices (which is
| my opinion is a GREAT thing), but of course the generators are
| completely optional.
|
| I don't have experience writing large LiveView apps but I would
| say that if you are familiar with any component-based
| frameworks (like React), I would take a look at SurfaceUI[1].
| It simplifies a few "gotchas" in LiveView (though I would say
| they are very minor gotchas and worth learning about at some
| point) and gives you a component-rendering syntax more like
| React. Once you get going, you'll learn that LiveView doesn't
| have all the headaches that come with bigger React apps (like
| having to memoize functions or comparing props to avoid a re-
| render and whatnot). The recent release candidate for Phoenix
| 1.6 has made strides for a cleaner component syntax, but if
| you're having trouble with LiveView, Surface might bring some
| familiarity.
|
| [1] https://github.com/surface-ui/surface
| whitepoplar wrote:
| Yes, I'm curious to hear about the patterns people use to
| structure their LiveView apps, particularly large ones.
| drunner wrote:
| Does this kind of technology exist in other languages in a
| similar fashion? I am aware of Blazor for c#, but I believe that
| uses webassembly and ships the entire c# runtime/gc making it
| very heavy.
|
| It is so cool that this just has a small js layer client side.
| CodesInChaos wrote:
| Blazor has different modes/variants. I think the server-side
| variant is similar to liveview and doesn't need a .net runtime
| on the client.
|
| > Alternatively, Blazor can run your client logic on the
| server. Client UI events are sent back to the server using
| SignalR - a real-time messaging framework. Once execution
| completes, the required UI changes are sent to the client and
| merged into the DOM.
| yewenjie wrote:
| Here is an awesome list of all such Liveview-like frameworks.
|
| https://github.com/dbohdan/liveviews
| keewee7 wrote:
| Has anyone tried server-side Blazor in ASP.NET Core? How does
| that differ from the LiveView approach?
| mwcampbell wrote:
| > We also shipped a live_redirect and live_patch feature which
| allows you to navigate via pushState on the client without page
| reloads over the existing WebSocket connection.
|
| This is one LiveView feature I've deliberately avoided so far.
| The reason is that when you replace real page loading with
| client-side navigation using pushState, accessibility for blind
| users suffers. When a real page load happens, a screen reader
| knows when the load is complete, and can handle it in an
| appropriate way, e.g. by beginning to read the new page. But when
| client-side JS updates the DOM in-place, a screen reader has no
| reliable way of knowing that conceptually, a new page just
| loaded. The usual work-around is to have an invisible ARIA live
| region that says something like "navigated to [page title]".
| That's better than nothing, but still a regression from real page
| loads. Of course, SPAs have the same problem.
|
| This really ought to be fixed in ARIA, but until then, I'll keep
| doing form submission and page navigation the old way. Still,
| LiveView is really nice for real-time updates within a page.
___________________________________________________________________
(page generated 2021-09-22 23:00 UTC)