Phoenix LiveView for web developers who don't know Elixir.

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video you're going to learn about something called Phoenix live you sowhat's Phoenix live view well it's a library for creating web applications that need to provide rich real-time user experiences similar to what you can achieve with single page apps now before we start to look at what live view is in more detail I want to first consider that problems that Phoenix a live view solves oh one more thing before I get started Phoenix live view works with the Phoenix web framework which is written in the programming language elixir but you don't need to know elixir or Phoenix at all to watch this video in fact this video is specifically for web developers who don't know elixir to get a sense of the problems that Phoenix wide views solve I want to walk you through a little thought exercise so imagine you've been tasked with building a basketball scorekeeping a web app that looks kind of like this basically there's three pages in this app as depicted in these rough wireframe drawings let me explain how this app should work there's a home page which shows box scores for the active games and from this page you can either start a new game by clicking this button or you can view the details of an existing game by clicking anywhere in a box score if you click on this new game button you'll be taken to this page where you can do things like change the quarters assign each team a name you can add players and you can keep score by clicking these two and 3-point buttons essentially this page is the scorekeeper page now I'm back on the home page if you click on one of these mini box scores you'll be taken to this page the game detail page which shows you the game score and provides additional details about the game when a player scores the score keeper will need to click the 2 or 3 point button for the player that's scored then the score should be updated here and the place should get added down here but that's not all that needs to happen additionally the new score should be updated in real time both on the home page and on the game detail page ok now that you've got the basic gist of how this application should work I want you to answer this question what kind of an application would you write to solve this challenge would it be a traditional server rendered multi page app or would you use a single page app I bet the vast people watching this video would choose to implement this as a single page app using something like react view angular or any of the other front-end libraries or frameworks this scoreboard app isn't very complicated but it does offer a richer real-time user experience that would be hard to implement in a multi-page app but offering this rich real-time experience is totally doable with a single page app in fact I bet most seasoned web developers watching this video picked the single page app approach without giving a much thought I probably would have made the same choice myself a few months ago but I'm gonna ask you to question your assumptions and reanalyze this choice considering the fact that there's a new option called Phoenix of Live View but before we dive into live views I want to briefly compare and contrast traditional multi-page applications and single page applications first let's consider the user experience these two types of applications can offer traditional multi-page apps can offer a decent user experience for simpler applications but you'll never be able to create rich applications like Gmail Google Maps or Google sheets if I were to plot the maximum potential user experience for a multi-page apps I'd say it's pretty low and in other words you're very much limited in what you can achieve okay what about the potential user experience of single page apps how does it compare with multi page apps well odds are you already know the answer to this you can create a much richer user experience with single page apps and I'm not even gonna bother explaining why because I don't think what I'm claiming is controversial at all next I want to consider the complexity for both of these options starting with multi-page apps relatively speaking the complexity of multi-page apps is pretty low you're more than likely using just one language on the back end and the tools you use and the build processes are relatively simple now let's consider the complexity associated with single page apps well to start you're probably still going to need to write server-side code for REST API Sora graph QL and possibly some other things like web sockets or background jobs in fact I'd say the complexity associated with multi-page apps still mostly exists in single page apps but as you probably know single page apps add a whole bunch of additional complexity because of all the front-end related technologies for example odds are you'll have to add JavaScript or typescript or elm or pure script or whatever front-end language you use then you'll be adding frameworks and libraries like reactor view plus you might decide to add a state library like redux and you're adding testing libraries like jest and transpilers like babel and dozens of other libraries in each of these frameworks and libraries adds hundreds or potentially thousands of their own dependencies so the bottom line is with single page apps you can create a really rich user experience but you're significantly increasing the complexity now obviously these two choices here and here aren't the only options you could use multi-page apps with something like turbo link or an PolyJet which can give you a slightly improved user experience but these libraries can't provide anything close to what a single page app can offer and of course you could try to use something like jQuery and a multi-page app but I have yet to see a good code base that uses jQuery extensively so good luck with that it would be kind of nice if there was a good alternative to these two extremes which offered the potential for a very rich user experience while at the same time maintaining a low overall complexity right well it turns out there is an option that offers this exact UX complexity profile and that option is Phoenix live view okay so what exactly is Phoenix live view well I'll explain what live views are in a moment but first I want to describe a simple mental model for single page apps and then I'll describe how Live View is kind of similar but different so when a browser makes an initial HTTP GET request to a server that's hosting a single page app HTML is returned then the browser requests the JavaScript and CSS that's referenced in the HTML file now if the single-page app doesn't support server-side rendering which most don't then the client may have to fetch some additional data from the server before it can render a view in the browser okay let's take a slightly deeper look at the parts that make up a typical single page app I think it can break a single page app into roughly three parts the data model and state client logic and view related functions and/or templates now a single page app still needs to talk to the server usually to send data back and forth via HTTP but there might also be a WebSocket to support real-time features okay with this simple model in mind let's start to look at what phoenix live views are and how it works and we'll see how live view is compared to single page apps when you make an HTTP request to a Phoenix live view at URL what sent back from the server is the pages fully rendered HTML which is really nice for SEO and it provides a much faster initial page load versus a typical single page app now what I've described so far isn't any different than what you get with a traditional multi-page app however this is where the similarity ends let me explain immediately after loading the live view page in the browser a WebSocket connection is made to the server now you see these parts right here that exist in a single page app the model or state the client logic in the view parts well these exist in the Phoenix will live view but they don't reside in the browser they actually live in the client specific process on the Phoenix server okay so how does this work well let's imagine a very simple example application a basic counter with an increment and decrement button so what's the data model or state for this application well really it's just a number which represents the current count in this simple example we'll say the count should start at 0 and keep in mind this state the count lives on the server so what goes here in the client logic well in this simple app we need to handle two things incrementing and decrementing of the number so there will be one or more functions to handle these two actions or events now this last part here the view or template parts is just a function in template that renders HTML that kind of looks like this okay so what happens when the plus button is pushed well it generates an event similar to what a single page app would do except this event isn't handled on the client-side it gets passed from the browser to the server via the WebSocket then the event is handled by a function on the server which changes the state from 0 to 1 now the server keeps track of state changes and when it changes the server automatically calls the view related function to effectively render a new view based on the newly updated state then the new view gets pushed down to the browser via the WebSocket connection and it's loaded into the dom actually the entire view doesn't get pushed down to the browser like I just depicted the view rendering process is optimized to minimize the amount of data sent across the web socket but thinking about it as a new view being generated on the server and sent back to the browser is effectively what happens okay I bet you've got questions about what I just described so let me answer what I think some of your bigger questions might be you might be wondering about this client or a live view process that's running on the server and you might be thinking that this is crazy and it's not going to scale very well when you have lots of users well keep in mind that elixir processes like this a live view process aren't processes or threads like you might be familiar with in most other popular programming languages elixir processes are very lightweight and it's very common to have tens of thousands hundreds of thousands or even millions of these processes running on a single server in fact several years ago the Phoenix team was able to load test a single Phoenix server with two million concurrent WebSocket connections and the associated processes here's another question you might have how efficient is sending the browser event to the server rendering the view on the server and pushing the view update back down to the client well I've described this process in a simplistic way but the actual implementation is optimized by tracking state changes and using diffing algorithms both on the server side and the client side so it actually works surprisingly well you might also be concerned about the latency associated with sending events to the server and having the view changes pushed back down to the client well this might be a warranted concern for users who are on a really bad slow network connection and have lots of drop packets however for users on typical high speed internet connections this likely won't be an issue unless maybe you're using the live view to write games with high frame rates in significant amounts of network traffic but even in these situations my view works surprisingly well I'm gonna pull up the chart I showed you earlier to emphasize something now the counter example I just walked you through is pretty simple and it's hard to call this a rich application but if you extrapolate the concepts I described I think you can start to imagine the types of things you can do with Phoenix live views you can build much richer applications with Phoenix live views while at the same time keeping the overall complexity low because you're only using one language elixir and you're avoiding all the front-end technologies associated with single page applications now to be clear there isn't parity between these two choices there are some things you can do with single page apps that you just can't do as well with live views for example I don't think you'd be able to implement Google Maps with live views and you can't create offline apps with live views however I bet the majority of single page apps in existence today could probably be implemented as live views instead of single page apps I don't know about you but I really like this profile you see here essentially you can build rich user experiences while minimizing complexity seems like a potential win to me now I don't usually quote Linus Torvalds but this quote seems appropriate talk is cheap show me the code okay well let's create a simple counter using Phoenix live use before I get started I've got a suggestion for those of you who don't really know elixir I won't actually be writing all that much code maybe 20 or so lines but you're gonna see some data types that you might not be familiar with and the functions that I write might seem kind of odd as well in the interest of time I'm not gonna explain in great detail every bit of code I write but I think you'll be able to understand the gist of what the code is doing even if there are certain parts of the code that you don't fully understand okay the first thing we'll do is create a new Phoenix project by using the mix command which is the elixir build tool then I'll key PHX new then I'll name this project counter and I don't want to use a database in this project so I'll add the no ecto option which excludes the ecto database library next I'll say yes to install the dependencies to use live views in a new Phoenix project like we just created there's a few one-time setup steps that you'll need to perform to configure the project to set this up I'm gonna follow this procedure from the live view get repo essentially copying and pasting a few lines of code or configs into a few different files no I'm not gonna walk you through each of these setup steps because I suspect these steps will be streamlined in the near future and of course you can flip this recipe in a cookbook at yourself so I'll perform these setup steps off-screen okay after configuring the project for live views I'll open the router file which is in the directory Lib counter web I'm going to add a routing rule on this line right here by calling live and I'll say when the URL is slash counter then handle this request with the module named counter live so you might be wondering what a module is moment as a beginner you can think of it as a container or a namespace for functions this contra live module doesn't exist but we'll go create it right now I'm going to create a new directory in the counter underscore web directory named live then in the new live directory I'll create a new file named counter underscore live DX this is the file we'll use to create the live view module I just referenced here in the router file next I'll define our module by keying def module and I'll name it Kantor web counter live which again is the same name we used in the router file then I'll key do and end to delimit the start and end of the module now i'll Kian use phoenix style live view which essentially sets this module up to be used as a live view module next I'm going to write a special function named mount which receives a session parameter that I'm not interested in using and then it takes a socket parameter this mount function will get called once when the live views web socket first connects to the server I'm going to set the initial count for the counter app in this mount function and here's how I'll do it I'll ki socket equals then I'll call a function named design singing the provided socket then for the second parameter I'll in turn atom data type named count and I'll set its initial value to zero this line right here basically adds our stateful value the count to the socket data structure now we need to return the socket from this function well actually we need to return the socket in one other value when you need to return more than one value from a function you'll typically wrap the values in what's called a tupple so I'll create a tuple by keying a set of curly braces then for the first element of the tuple I'll add the okay atom and the second element will be the updated socket since this tuple is on the last line of the function it becomes the return value next I'll define another special function the render function that takes an assigns parameter this assigns parameter is what's called a map in elixir essentially it's a key value data structure that contains our state will count now in this render function I'm going to use something called the sigil by keying it Tildy capital L then I'll create a multi-line string by keying three sets of double quotes okay so what's the sigil thing well this particular sigil allows you to add an inline HTML template which will get displayed in the browser you don't have to write your HTML templates like this but in this simple example it's a pretty good option so for the template I'll add an h1 tag and I'll say count colon and I'll use a special embedded elixir tag to inject the count by King @ count this @ sign essentially pulls the count out of this assigns map next I'll add a button that shows the plus sign then I'll add a button that shows the minus sign let's see if this works in the browser so I'll save our files and in the terminal I'll start the server by King Mix PHX server then I'll open up the browser on localhost port four thousand now what you're seeing here is the default page that's automatically included in newly generated Phoenix projects but for us to use the live view we just created we need to navigate to the path slash counter and as you can see the count is zero and we've got a plus and a minus button if I click on the plus and minus buttons mom nothing happens because we haven't configured these buttons to work with Phoenix live views so let's go fix that to get these buttons are working and we've got to do two things first we've got to add a special attribute to the button named PHX - click and i'll set its value to the string increment adding this particular attribute sets this button up to send click events back to the live view process that's running on the server but now we need to add a live view function to handle this increment click event so I'll define another special function named handle underscore event the first parameter will be the event name in other words this name you see right here increment I'm gonna do something in this first parameter that'll probably seem kind of weird if you're unfamiliar with elixir instead of putting an identifier here like message I'm gonna key in the literal string increment I'll explain what's happening with this first parameter in a moment so just hang with me I'm not interested in the second parameter so I'll just key in the underscore and the last parameter is the socket that contains the state of our lives view in the body of this function I'll create a count variable and I'll bind it to the current count which can be accessed by King socket assigns count then I'll add one to it next I'll update the socket with the new incremented count a king socket equals then I'll call the assign function again passing in the socket the field name count which again is an atom data type and lastly the updated count now I'll return a tuple with a no reply atom in the updated socket okay so here's the gist of what we just did when this button is clicked in the browser the event is sent back to the server over a web socket and it's handled by this function here which increments the count now since the state of this live view has changed this render function will automatically get called and effect a new view will be generated and sent back down to the browser let's try this out in the browser so I'll click the plus button a few times and the count is incremented cool of course the minus button doesn't work but we'll fix that right now so I'll add the attribute thx - click and I'll set it to a new event name of decrement next I'm going to copy the handle event function then I'll change the event literal from increment to decrement and I'll change the plus sign to a minus sign okay if you're new to elixir you're probably looking at these two identically named functions and wondering what's going on here well in elixir you can have multiple function clauses with the same name and the way this works in this particular case is if the first parameter passed into the handle event function is the string increment then this function Clause gets called however if the first parameter is decrement then this function Clause gets called okay let's go see if this works so I'll click the plus button a few times and that works then I'll click the minus button a few times and that works as well cool I'm going to open up the developer tools and we'll take a peek at the data that's being sent on the WebSocket so I'll click the plus button and as you can see a message is being sent to the server which represents the button click event then you immediately see the response frame right here notice that the response is an HTML it's just the new count which you can see here if I push the plus button again you see another increment request goes to the server and you see another response with a new count of two so as you can see very little data is sent back from the server let's go watch the Dom elements when a view update happens keep your eye on this part right here when I click the plus sign notice that the entire dumb isn't replaced only the part of the dumb that needs to change is updated it's pretty efficient okay I've barely scratched the surface of what you can do with Phoenix alive views but hopefully you've got a pretty good sense of how it works alright my view is a pretty cool new technology and I'm very bullish on it I think it hits a sweet spot and that you can build very rich applications without adding much complexity let's circle back to the basketball scorekeeping app that I talked about in the beginning of this video so how could we use the live views for an application like this well each of these pages could be a live view then I probably keep the state of each basketball game in a separate long-running process then when a player scores the scorekeeper page would send an event back to the server's live view process which could then send a message to the game process then the game process could send messages to these 2vy view page processes then the live view processes would update their state and push the appropriate view changes back down to the browser if your new dual-x are in phoenix and you'd like to learn more you should check out my new course elixir in Phoenix for beginners you'll find a link to the course on this page also if you want to be notified when I release new videos like this one you can join my mailing list at northern com /join hey thanks for watching this video and I hope you found it helpful
Info
Channel: knowthen
Views: 42,239
Rating: 4.9418283 out of 5
Keywords: Elixir, Phoenix, Phoenix LiveView, Rich Real-Time UX
Id: U_Pe8Ru06fM
Channel Id: undefined
Length: 22min 37sec (1357 seconds)
Published: Tue Nov 05 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.