Blazor, a new framework for browser-based .NET apps- Steve Sanderson

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
alright then let's start this thing well hello hello NDC London people it's really nice to see you all firstly well done for coming to this session good choice I'm really pleased to see you are clearly people of good taste so I'm quite happy to be spending the next hour with you so my name is Steve and I'm very much looking forward to showing you this thing blazer I'm sure some of you have seen it before but let's find out can you do your hands in the air thing if you've seen blazer or razor components something like that before all of us like 3/4 of you at least that's great and just out of interest how many of you went to Dan Roth's talk about razor components this morning that's like about third of the room as well ok good so you are going to see some overlap with this talk but not too much ok there's gonna be a lot of cool new stuff as well ok so what is this thing why we bothering to look at it you know for those of you have not heard about this before blazer is an experimental single page application framework from the asp net core team where we're building on the ability to run dotnet code inside a browser in webassembly to give you the ability to be more productive and happy than ever before that's the idea ok so in this talk I'm going to be showing you quite a bit about how how it works you know how you can build stuff with it what the process of actually creating UI with this thing is but there's also going to be quite a big part of like why are we doing this anyway what is the point of this why should you care what is changing in our industry that is creating this new possibility anyway so to set that context let's think a little bit about how web development works today ok so web development today you're going to have some code that runs on a server somewhere might be a server in the cloud might be just some dusty box that's under your desk or something like that but it's going to run some code and that code might be in dotnet my bein Java might be node might be go it might be something else but it's some code running in a server but you don't just want to write something in a server you want to make some UI appear in someone's web browser and how are you going to do that well you're probably today going to use one of these single page application frameworks it's the most mainstream way of building an entree will you I and whether its angular react view something else it's gonna be running on the JavaScript runtime now maybe you write your code in typescript or flow or something else that compiles to JavaScript but basically it's running on the JavaScript runtime so it's gonna look and feel like JavaScript which is a little bit of a shame isn't it because this means you've got these two different worlds to try and make talk to each other and not only that it's just sad on a principle level because if as an industry we've built all these amazing languages and platforms why can't we use them wherever we want why are we limited to this one little cluster of languages around javascript in the browser wouldn't be better if we could use anything we want anywhere we want and that's the idea behind web assembly web assembly is a way of running any code you want inside a browser doesn't have to be JavaScript we'll talk about how this works internally later in the talk but just for now let's say this is a great way of running whatever code you want and it's supported in basically all browsers including mobile browsers at least as of about 18 months ago so we're in good state with web assembly so if we can run whatever code we want inside the browser on web assembly that naturally leads us to think well could we run net inside the browser on web assembly and when we found out that we can do that that brings us very happily to Blaser which is a UI platform built on top of this stack so this is for you to build your sophisticated UI's on top of dotnet running inside a browser okay so would anyone want to do that well would there be any benefits what who should want to do that why would we care so there are potentially quite a number of advantages to doing this versus traditional approaches to building your web UIs and I'm going to go through some of them but you don't want to just hear me keep talking about this you want to actually see it for yourself presumably so I'm going to show you some examples of each of these things just now let's start with the advantages of using the c-sharp language inside a browser okay so I'm going to switch over to a demo application now and I've got this blazer application here that I can start up and run inside my browser okay so it's a pretty traditional typical looking web application it's got a couple of different pages in there we've got to do list we've got this thing where we can fetch some weather forecasts from the server and we can do some forward backward client-side navigation and it's all interactive so let's have Meg Blaser profit okay so that's my to do us and it's all working fine and it's interactive inside the browser sort of think you would normally use a JavaScript framework to build but we're not using javascript here at all so if we have a look at what's inside our solution here you'll see what we've got is a bunch of CS HTML files which is razor talked about that in a second and besides that we've got CSS we've got HTML and we've got traditional c-sharp files but no JavaScript because we don't need it because we've compiled dotnet and we've we've run it in such a way that it can run inside the browser okay so what are these CS HTML files well if you've done any OS p-nut development in the last few years you'll be familiar with CS HTML being RAZR files now razor is a syntax for combining c-sharp and HTML in one file in a way that they can work together really nicely so let me give you a couple of examples of that ok so firstly how does this very simple thing on the home screen work it's just some static content so how do we make some static content show up in our blazer application well we make a component Emblaze are all parts of your UI our components the whole application is a component pages are components layouts of components groups of UI elements they're all components its components all the way down so that's what each one of these CS HTML files is and the simplest component is very simple indeed it's just some markup just static markup but what's this okay so up at the top we've got this one special thing which is ID Eric a directive and the page directive says this is the component that we want to use if the user is on the home page and we're going to display this static markup so that's pretty simple okay what about the slightly more interesting thing of this to-do list okay where we can actually enter some stuff and the UI up days well let's look at the code for to-do list there's quite a bit more in here but I think we can understand this quite easily let's go through it so firstly we've got the page directive up at the top again to control which URL we respond to and ignore this stuff from Annette down here we've got a functions block and inside the functions block we can put some code and since this is net and we want to write this in c-sharp we are writing some c-sharp curve right here inside our component so how does it work well we've got this text box here which says whatever value enter we're going to put this in this field called new item text which is defined down here okay and then this form says when you submit it we're going to call this method add item which is a c-sharp method defined down here and we'll take the item that you've just typed in and we add it to our list of items which is a list of string and then we want the box to get cleared out so we'll set a new item text back to null okay and then all that's left to do is iterate over all the items in our items list and for each one we'll just display it on the screen so I hope you will agree that this is a pretty simple way of writing interactive UI okay very simple familiar components based programming but with dotnet combined with HTML alright so last one that I want to show you as an example is this one where we're fetching the list of weather forecasts now this is to demonstrate how we can interact with some external services to get data and if we look at the code in there you'll see again we use this page directive but we're also now using inject inject lets us interact with s pinettes dependency injection system so that we can get services that are defined within our application and in this case we're getting an HTTP client so that we can make some calls to fetch some data okay now we'll ignore all this stuff for a minute and let's look down here and we can see that when this component is first initialized it's going to asynchronously do an HTTP GET request to some endpoint to fetch some data now as it happens it's just a static file that I've gotten disk but it could be anything it could be some dynamic code that runs on the server and when the response comes back we're going to deserialize it as an array of weather forecasts and I've defined the weather forecast type right there so then we want to display that on the screen and if we wanted to we could do it in a similar way two other to-do list works we could have a for each loop and we could say for each item I want to make an HTML table row and I'll display the contents in that and that would work perfectly fine but I wanted to make this a little more interesting so I've got this component called MDC list one earth is that well you won't see that my application has this attractive kind of purple theme and this pretty list here well this is all coming from the material design library okay so this is to show you that in blazer we can pull in component libraries that have got ready-made components for us so I've got this material design components list and I can pass my forecasts to it and I can pass all these other little template parameters that control how stuff get displayed in the list there all right so that shows us how we can use c-sharp in a remarkably simple way to build interactive UI but what's this next thing then the net dotnet ecosystem how can we make use of the dotnet ecosystem inside a blazer application well consider the following scenario okay it's Monday morning you've been working all weekend and you've made this weather forecast thing and you excitedly show it to your boss or some kind of business analyst in your company and they go well done code monkey you've done a good job but there's one little thing that I need from you I need to be able to export this to excel so that I can do some business analytics on it and your thing are great at export to excel okay fine I'm gonna make you a CSV file I can I can output a comma separated text file that's going to be good and the business analysts will say no I don't want a CSV file I want a proper spreadsheet I want colors I want conditional formatting I want charts this is my life don't take it from me okay I want a real spreadsheet and you'll say Oh gray right how we're gonna make real spreadsheet and the answer to that is really easily okay because you're a darknet developer and you've got access to the whole dotnet ecosystem and doing things like making spreadsheets is super easy so how are we going to do it right we're gonna go and we're going to add a reference to an external third-party package okay so let's go to new get dog and we're going to search for excel all right and what's going to come back from there a bunch of things that help us to work with excel and if we look closely the one that's got by far the largest number of downloads five point eight six million of them is this thing called EP plus so you say okay it's got a lot of downloads therefore it must be the right thing for me to use so I'm going to install that into my application right now and it says okay accept some terms yep great I don't want your readme thank you and now I've got the power to make Excel spreadsheets so what do I want to do first I want to make a button that appears the bottom of the screen here for downloading this as a spreadsheet so I could use a traditional HTML button if I wanted to but hey since I've got this material design thing I'll use an MDC button so that it looks good and then Visual Studio says hang on you want me to invoke this download a spreadsheet well sorry but there is no such thing and that's going to be a problem so you'll say okay fine right I'm going to create this download a spreadsheet method that we're going to invoke when they click the button okay what am I going to do in there well I better put some logic in it so you'll go and you'll read the documentation for EP plus and it will tell you that what you need to do is new up an Excel package and then you can do stuff like you can add a forecasts tab into the list of worksheets in this spreadsheet and then we're going to say all right browser I want you to download this thing as a file called forecasts dot xlsx and the contents will be the bikes from that spreadsheet that we've just created on the client in our application so let's load that now let's see if when I press this download button does it download a real spreadsheet ok says ok you're opening forecasts do you want to open that in Excel is of course so I choose yes and Excel starts doing all its stuff and when that comes up hopefully we'll get a forecast now it's empty right there's nothing in our spreadsheet because I didn't put any data in it but we have got this forecasts tab down here which starts to show that we're on the right track so what do we want to put inside our spreadsheet so again you go back to the EP plus Docs and you read how to go about inserting data in search and we'll decide that what we want to do is we want to start this cell b2 b2 and then we can use c-sharp link query to fetch whatever data we want for our in memory weather forecasts array and we can use link expressions like where f dot temperature is greater than hundred a that one and okay so we've fetched our data and we have put it inside our spreadsheet okay but we can do some more cool stuff than that let's make this a little bit more interesting so first let's add a computed column here in our spreadsheet where we're using this formula to calculate temperature E and F based on temperature C very good and let's also dump in loads of code that you won't have time to read that's going to set horizontal alignment background color and bold fonts and other things like that all right and then finally just to really show off let's put in a chart okay just because that's what our business analysts really want it so let's go back and try that now so if I hit the download button then again it's going to say you're opening this forecasts spreadsheet and when that comes up this time instead of being empty we've now actually got our data and it's got colors and it's got formulas it's even got this completely insane pie chart that shows but how much of the temperature happens on each day of the week whatever that means okay so there we go we've done a super job there of pulling in a thing just an arbitrary third party thing from the dotnet ecosystem and we were able to use it inside our application all right last benefit full-stack what on earth do we mean by that why is that a relevant term in this context okay so the application I've shown you so far is a true client-side web application it does not have any dependency on there being net on the server at all you could host this on a PHP site if you wanted you could more realistically host it on node or or some other kind of modern framework or if you wanted to you could export it all and you could deploy it to github pages or to Azure blob storage or to some other static file store there's no requirement for there to be done out on the server but what if you do have done it on the server are there potentially some advantages that you can use to tie your front end and your back ends together in a useful and interesting way so let me show you I'm going to close this project right now and I'm going to switch over to a different version of it that's almost the same except this one is going to be based on an a spinet core server so let me just run it first so we can see that this works and that's not in any way what I wanted to run let's set this thing as the start of project and we can close all our windows there we go alright so let's start this up now when that comes up you'll see that it's basically the same thing that we had before it's got the same set of components in it the same pagers the same basic behavior so we've got all this stuff but if we look at our source code there's now three projects instead of one we've got the client project which is basically the same thing that we had before so this is another blazer client-side web assembly application it's got the same set of pages and components and stuff it behaves the same as before but we've also now got a server project and that is an asp net core server and we can use that as a place to put things like our back-end data services that we want to invoke or any other things that we need a server for like authorization or you know database access that sort of thing okay and then finally and perhaps most interestingly we've got the shared project and this is a really basic thing it's just a dotnet standard to our class library which you can just put any code in that you want to share between your server and your client because I've set up references from the client project and the server project both to the shared so they both get whatever code is in there and as an example I've put the weather forecast type in there so now if I go and look at the forecasts on the client here you'll see that before I had the forecast defined as an inline class here so the client was defining its own weather forecast type but now it doesn't it just gets that from the shared project and similarly on the server the endpoint that we're calling this sample data controller weather forecasts thing which is going to return the data well it doesn't define weather forecasts either it gets that from the shared project so the point is whatever stuff we want to share between server and client we just stick it in here and it's there and it's not just for data you can also use that for bits of logic as well here I've got some logic that computes temperature Fahrenheit based on the sea and I could also put in things like validation rules or other business logic that we want to share between client and server in an incredibly straightforward Manor okay so those are three ways in which it can be really nice to build this kind of application but there are various other benefits that we could talk about as well you know performance dotnet core on the server is just about the fastest mainstream web platform that there is if you can check the independent tech and power benchmarks if you want to verify that sort of thing yourself it's extremely fast we've got we've always had the best-in-class tooling pretty much Microsoft has been well known for for having really outstanding industry-leading tools in Visual Studio with the intellisense and debugging and all that kind of stuff so you know all that stuff comes with that and then finally in terms of stability well in dotnet world the culture is basically we assume that your projects are going to be around for like five years or ten years or something like that so we try really hard to keep things stable over that kind of period and we're not just completely changing what set of libraries you're supposed to use every three months now stuff does change sometimes but generally it's a more stable world that you might see in say JavaScript land okay so that gives you some ideas about what this stuff is all about but I haven't really shown you much about how it works on the inside yet so the way this stuff works is that we've got three technologies stacked up on top of each other making this sort of technology cupcake that we're able to enjoy and feel delighted by okay so at the bottom of our technology cake we're building this stuff on web assembly and I've said to you already that web assembly is a way of running whatever kind of code you want inside a browser but how does that work okay well web assembly is a bytecode format that's what the spec is it says that here's a way of describing some programs in a low-level bytecode and browsers are supposed to implement support for executing yet and the good news is they have implemented support for doing that all the mainstream ones including mobile ones have done that but what does this bytecode look like you may well never have actually seen the bytecode itself or maybe you seen it but you wouldn't really know how to create it yourself so let's have a go I'm gonna create a small web assembly application right now well call it an application might be a stretch because it's going to be very very simple okay and this has got nothing to do with dotnet too use blazer this is just going to be pure webassembly on its own so that you can understand that right so why I've got here in this directory is a few files including Fibonacci C I expect you can probably guess what that does but let me show you it's a simple C program that is going to compute the Fibonacci sequence which is just a series of numbers that are defined mathematically it goes 1 2 3 5 8 and so on after that I can add but that's how it works and my primitive nachi function is simply going to take the number of terms that we want to print and it's going to say ok as long as you've got some more stuff to do then I'm going to print out the current term I'll compute the next one and I'll print it I'll compute the next one I'll print it and so on until we run out of things to do so that's written in C and as you know C doesn't normally run inside web browsers but thanks to web assembly we can compile C to web assembly and then run it so let's have a go at that so I'm going to show you these are the files that we've got right now but I'm going to compile Fibonacci see using the M script and C compiler to produce something that can run inside a JavaScript runtime okay so that compiles it takes a few seconds and when that's done you'll see we've now got these two new files Fibonacci j s and Fibonacci dot wasum wasum webassembly is the actual binary bytecode format so we can't read that directly it's just binary stuff but I'll show you what's in there in a second and the J s1 is a wrapper file that is enable that intends to help you load it and run it inside the browser now that's what I want to do I want to run it in my browser so I've got this index.html pipe file that I can load in my browser and show you what's in there well it's extremely minimal not really even valid technically but it's going to work and it's going to load this Fibonacci J s file and then run it so let's set up a little static HTTP server that I can use to execute that stuff and then I'll go back to my browser and I'll go to localhost port 8080 and we'll have a look in the browser console and we should see that indeed it is actually printing out those first 10 terms of the Fibonacci series so we're running C inside the browser but how does it work what's going on really so we'll have a look in the the debugger and actually in order to make this easier to understand I'm going to recompile this with additional debugging support so I am compiling in debug mode and I'm going to admit source maps as well and once I've done that and I go back into my browser and reload you'll see now we see Fibonacci see shows up in the dev tools and if we click on that we can see our C source code here which is it which is the stuff that we're running and I can even do things like set a breakpoint on there so if I hit reload we'll now hit the breakpoint and it appears that we're stepping through C code that's executing inside the browser which is pretty cool but we're not really actually executing C at all what we're really executing is the web assembly bytecode and it's just been mapped to this source code by the source Maps so let's have a look at the actual byte code we can see that in here now normally the Wesen file on disk is a binary file that you can't possibly read but Firefox is kind enough to represent it to us in this kind of human readable format well I appreciate that you have to be the right kind of human to read this but I think that we are the right humans to read this we can do this all right so what is inside this crazy-looking thing well we can see it's got all these function imports and exports but I don't really know what that most of that stuff is let's just search for print Fibonacci okay so we can see here's our code this is the thing that we were writing and what does it do well all these instructions what are they if you would look closely you might see that that's kind of similar to the dotnet instruction language MS IL is so just like MS IL it's a stack based virtual machine that operates on a fixed set of primitive types and so we can compile whatever code we want to to this format as long as you've got the right kind of compiler for it and the sort of thing it can do is it can do things like define functions it can have locals it can do loops it can do these numeric operations like subtracting one and it can call out to system functions like here is where it's calling the print thing okay so given that we can even set breakpoints inside web assembly as well so let's do a reload on there and we should see that we've hit some break points and we can start stepping through the actual web assembly code as well all right so I hope that somewhat makes sense to you that that's what's at the bottom of the stack here we're able to compile stuff to this bytecode format it then runs inside the browser and web assembly is really fast one of the key design goals for web assembly from the beginning has been performance and generally speaking code that's compared to web assembly runs within a factor of two of executing just natively if you compile it to native x64 machine code or whatever else that you're normally target okay so that's the idea with web assembly and given all that we might think well right let's run some dotnet on that how are we going to run down on it well the obvious way to run not on web assembly would be to somehow compile the dotnet machine code the msi l2 web assembly by code okay if we could somehow do that then we could just run it inside the browser so that would be cool but that's not actually what we've done what we've done instead is we've taken a dotnet runtime and we've compiled that to web assembly so we're not compiling your code to webassembly we've already compiled the runtime to webassembly and the runtime that we've compiled is in fact mono and you might think why mono why did you why mono the answer to that is that Microsoft has got three net runtimes that we share right now we've got the Donaire framework which is the CLR we've got a dotnet core core CLR and then we've got mono and these all have different places and different purposes the idea is that for you as a developer you don't have to care which of these things your code is running on you code against dotnet standard and your code is going to run on any of them just the same but why did we pick mono for this then well it's because mono is our preferred net runtime for portable client scenarios Mona is a really portable code base and so it was the by far the most practical one for us to compile to web assembly so that's what we've done and that is something that the dotnet team so that the mono team is committed to shipping as a fully supported production runtime so that you can run your dotnet code inside the browser on web assembly ok but how do work right I've just told you that this thing exists but I've not really shown it to you so let me show you a little bit of mono running in on top of webassembly and I can show you that inside the application that we've been building already what are we actually sending to the browser how does the browser know to load mono and to execute our dotnet code inside it let's have a look at the HTML source code alright so our HTML that we're sending to the browser is just normal HTML it's got a bunch of CSS and body tags and things like that we've got this loading animated progress bar which is just static HTML that I've put in there but nothing really interesting happens until we get to the bottom here where we load this javascript file components web assembly is and that is something that's built into blazer so when you create your new project with blazer that thing is already there you don't have to see it we just know how to serve that and that file is what knows how to start up mono and load your application into it so let's see what the browser is really doing if we open up the network tab here and I'm going to hit reload and then we'll look closely at what stuff this thing has actually sent down to the browser so we send that initial HTML that I just showed you and that contains instructions to load various things like CSS and then it loads components webassembly j/s and that tells it to do a few more things to start up your application and importantly it loads mono wasum and that's what I told you we've done with mono we've compiled it to a web assembly binary using M scripting the same way that I compiled Fibonacci dot C to awesome the same thing has happened with the mono codebase to make this file ok and then once that's been loaded we can load your regular dotnet assemblies into it so we're not compiling these two web assembly they're just normal net dll's that have been built by the normal c-sharp compiler and we could load them and run them inside the mono runtime which itself is running on web assembly right so you may be thinking hang on you're loading an entire dotnet runtime into the browser this is going to like hundreds of megabytes or something how big is this thing and the answer to that is currently it's about two megabytes so for a dotnet runtime he's small and we quite pleased with that but at the same time we're not pleased with that because two megabytes is big for a webpage and there are a lot of scenarios where you want your application to be quite a bit smaller than two megabytes maybe you are building some kind of internal line of business app and it doesn't matter to you at all we hear a lot of customers say like I don't care if it's 10 Meg's that's fine with me but if you're trying to do some public facing thing you probably want it to be smaller so we're working quite hard and the mono team is working hard on finding ways of cutting that size down but you know 2 Meg's is where we've got to at the moment of course this is all cached so if the user comes back later they're not going to fetch any of that stuff a second time I only downloaded 227 kilobytes this time and that's because I'm not even caching various things to do with bootstrap and other stuff you can make the size down to kind of nearly zero when it's cached but it's 2 megabytes if it's not cached ok so that's how we're running mono on top of web assembly final thing the topmost and most delicious most layer of our technology stack is blazer and that is the UI framework that we've been using so that is the thing that is defining not only how our application starts up but what all our components are and how they're able to interact with each other right so I've shown you a bunch of components already but I've only shown you some fairly simple ones you're an advanced and ambitious kind of group of people I think so wouldn't you like to see some advanced components I think you would so let's go through two scenarios where we can build some more interesting things with components ok we're gonna start with something that sounds very smart indeed templates and generics how can we make some generic template or two components well what I want to show you is let's look at this thing here I mentioned earlier that i'm using this MVC list okay now what is that and how could we make our own special list components ourselves doesn't remember what it looks like it's displaying this attractively formatted list with icons and subtitles and things like that and that's all coming from this external component library but what if we wanted to do this ourselves what if we didn't have MDC list let's get rid of it and implement it ourselves shall we so and to show you what the equivalent inline code would be it's kind of scary you're not gonna like the way it looks but this is how it is if we wanted to make this material design list just by ourselves we'd create an unordered list and we'd put this massive pile of unpleasant-looking CSS classes on it and then we'd say okay for each of the weather forecasts will iterate through it and then we'll make more and more markup during which will display the icon and the date and the temperature and other things like that so let's see if our homemade material design list works just the same as the the predefined one so let's come back and reload and it should render more or less the same thing it's slightly different it's not displaying the temperature in Fahrenheit anymore but you know it's basically the same thing I just didn't make it exactly the same okay so we can do this ourselves but once we've done this we don't want to keep reinventing this every time we want some way of reusing this component over and over again the general idea of a material design list so how can we make our own list component I'm gonna do that right now I'm going to add a new item and I'm gonna choose where as a view and I'm going to call it super list all right so what can I put in my super list well the first thing is let's think about what data our list is going to need we want to be able to pass in the list of things to be rendered okay so I'm going to define a parameter on my list here a parameter is just a property that's got this special parameter attribute and I can pass in an enumerable of weather forecasts that we want to render and then I'm going to put some initial markup in outside this component and it's going to be the same thing that we saw before so it's going to have all these CSS classes and it's going to say for each one of the things I'm going to display something and initially I'm just going to display the date all right so let's keep it simple to get started with and then over here on the consumer side let's get rid of all that markup and I should see in intellisense if my intellisense was alive it's there yeah so I've got my super list here and I can start making use of that okay but I want to pass in the list of forecasts to it so that's what I'm going to do let's save that I'm going to rebuild and then we'll check that we are actually using our super list component now remember sue palace only displays the dates and it does so in a very basic and rubbish fashion so we've got some more work to do firstly I do not want to display the dates in this format I want to be able to customize the format so what can I do here well I could have a parameter where you pass in a format string or something like that but I want to be even more advanced than that I want to be able to pass in some arbitrary markup that describes the way that the title is going to be rendered to this primary text so I'm going to define another parameter here and it's going to be called title and the typing of it might be a little bit unfamiliar so it's going to be of type render fragment that's a special type that components know about and that represents an arbitrary piece of user interface so the person using the component can pass in whatever markup they want which can contain logic or other components and we're able to render it from here so now instead of just rendering item date I'm going to invoke title and I'm going to pass the item into it it's a generically typed render fragment which operates on a weather forecast so I'm going to call it and so will render whatever markup has been passed in for each item and now if I go back onto the consuming side here I should be able to specify a title okay and I can put in here whatever I want to using this magic keyword context okay and if I type that correctly like let's make sure I've got the type correct and I try to type context then intellisense should say okay I know what that is that is going to be a weather forecast so I'll prompt you with what all the properties that are on weather forecasts okay so I want to display the date and I want to be able to display it in a particular format so I'm going to pass a format string here to control that it gets rendered like this right let's try this out let's see if we now rendering our dates in a more attractive format so we reload and indeed we are now displaying it in the way that we wanted okay but I don't just want to display the date I want to display things like an icon and summary text and other things like that so I'm going to go back to my super list and I'm going to say you can pass in as many different templates as there are things to do useful stuff with so I'm gonna say we're gonna have an item icon template a subtitle and actions and we're going to make use of all those in the rendered output so let's get rid of this and I'm going to just paste in a big chunk of stuff that displays the icon and the title and the subtitle and all that stuff okay and then back over here on the caller side I can now pass not just a title but I can pass all the other stuff the icon the summary I'm displaying the temperature in this particular format that I'm controlling over here when I use my super list okay let's try this one more time reload and now we should see okay great it's looking good we're displaying the icons we've got these things over here on the right we've got pretty much only usable list but it's not completely reusable yet because at the moment is completely hard-coded to work with weather forecasts what about if we want to rather render other things that are not weather forecasts and this is where generics come into it so generic components are very very cool you can do this I can say I want to declare a type parameter and that's just like a generic parameter on a c-sharp class and so now instead of using weather forecast I'll say okay give me an enumerable of T items and also a bunch of templates that in a strongly typed way operate on T item okay and now I can render anything I want so then I can go back over here to where I use it and I can specify what I want T item to be so let's say I want T item to be a weather forecast all right so now I can pass this list of weather forecasts in and v/s knows that each one of these things is going to be a weather forecast so we get the right intellisense okay but what's cool is still then that is what if we don't specify what the type it is well that's great too because we've got generic type inference we don't have to specify what it is the fact that the parameters we've passed give us enough information to know what the generic type is means that it's just going to work anyway so we still have all the correct intellisense showing up we are very happy people okay last thing we might want to do is it's a bit strange that we've got this word context here but what is that why is that the right word so let's say we want to change that for something else let's say I want the variable to be called forecast instead and now vs is going to say to us what is this context thing you're speaking of I don't know what that is but I do know what forecast is because forecast is now the name for each item here so I can change all these contexts to forecast and the code starts to make a lot more sense so we've pretty much completely recreated everything that we had in the MDC list component and we've made our own reuse of a list it's not limited to working with weather forecasts it can work with anything all right so that's one type of advanced component let me give you another one what about this cascading stay what is that it also sounds pretty advanced right so all the components I've shown you so far they contain their own state they just deal with their own little world and they don't have to interact with other components in any way but what if you need to have a way of coordinating stay across all the different components in your application well there are many ways you can do that because this is just a dotter application you can use whatever patterns you want with c-sharp and events and statics or dependency injection whatever it is that you want to do but Blazer or components the underlying UI technology have got a good feature for this that help you to coordinate stay across your application so as an example of that let's imagine that I want to make my application fee mobile I've got this purple button here but what if I want it to be different colors at certain times and I don't want all my components to embed information about themes I want to just define that in a central place so I'm going to add a new class and I'm gonna call it theme info and I can put whatever properties on here I want to represent stuff that I can theme and what I'm going to put in is just this one thing call button class I could put more stuff in if I wanted to but that'll do for now all right and now I want to be able to pass an instance of this to all the components in my application so I could do this wherever I want but I'm going to go to my main layout and I'm going to say okay I'm going to use this built-in thing called cascading value and that can provide a value to all the parts of my UI that are inside this element and v/s is saying what do you want me to pass you haven't said so I'm going to say what I want to pass is not that what I want to pass is this I want to pass a new theme info okay so I'm creating a theme info and I'm saying the initial button class is this button warning thing and I'm passing that to all the other parts of my application and so then I can receive a theme info wherever I want to I'm going to go over to my to-do list which we saw earlier and I'm going to make a parameter where I can get that current theme now as you know normally we use parameter to get parameters but this is not a normal parameter this doesn't just come from my parent this comes from anywhere in the hierarchy above me so I'm going to have a cascading parameter and so we can get the current theme cascading down through the UI and then up here on my button instead of using button normal I'm going to use current theme button class so whatever it is that's on my theme so let's build that now okay I'm going to come over and hit reload and so now instead of that purple button you can see we've got a different colored button because that's coming from the theme which we've been sharing so that is how we can supply static content but cascading value is cool because it's not just static stuff we can pass but also stuff that changes so let's say I want to make this button class change I'm defining it as a field with an initial value of button normal and I'm going to use that and then so that the user can edit it I'm going to put in a drop-down list and it's going to be wired up to that button class so whatever you choose from here that's going to be the value for this field and there's a few different options that we can use okay so now if I start my application again the button is going to go back to being purple because that was our default theme but if I change it here I can have orange or I can have blue and that theme information just automatically gets distributed through my application I don't have to think about subscribing for changes or anything like that the is able to flow correctly throughout my tree of components great so there we go there's two advanced scenarios for components now that's all very well but this is stuff that we've already shipped if you've been using Blazer for the last few months you've probably already seen that stuff and what you maybe you would like to see is stuff that we have not shipped yet what's coming soon what are we working on all right so I'm gonna show you a few things now so let's start with debugging now we've already got some debugging support we can already do some debugging in a browser if you're in dance talk early this morning you will have seen that I'm gonna do a very quick recap of what we've already got just for anyone who hasn't seen them so I'm gonna switch over to Chrome because that's the browser we're supporting debugging in right now and I'm just going to make sure that I've cleaned my application and I'm gonna rebuild it everything to give me the best chance of success here and then I'm going to start my application up when it's rebuilt and then hopefully I'm going to show you how we can do some debugging inside the browser so I'm going to go over to Chrome and I'm going to start my application up and I think all right how am I going to do this debugging then because I can't really use vs because vs doesn't know about chrome you know in web application up webassembly applications and I can't really use the browser dev tools because they only show me things to do with CSS and JavaScript and things like that so how can I do bug dotnet code well we've set up a debugging server that runs with your application that the browser can connect to in order to get information about what your application is doing and if we look here it tells us use this debugging hotkey shift alt D alright so let's try it as su happens if I press shift D well it opens a new window and it says ah it's not going to work because the debugging server can't connect to your browser just yet because you're not listening for debug connections in this browser so what you do is you copy this thing that it tells you about and close your browser start it up using the instructions and then this time hopefully the debug server will be listening so if I press this tab here and then I start it up then hopefully I can actually see not just the usual stuff that I see not just the assess on the HTML but also the files from my project the sea shark files like here and even the CS HTML files like here okay and what's more I can set breakpoints so let's say I put a breakpoint here when we try to add an item to our to-do list and just so we can see let's split the windows and then I'll try to add an item here and when I do it hits the breakpoint inside the browser so that's pretty cool right we're able to do some net debugging inside the browser very good but this is old news this shipped months ago wouldn't it be nice if there was a way of doing the same debugging but not inside the browser but where your surf code actually is inside Visual Studio that's not been a thing that we've had support for but would be nice wouldn't it so let's see if we can make it work shall we I want to make Visual Studio connect to this browser so I'm going to copy the URL and I'm gonna do attach to process and I'm gonna choose the chrome dev tools protocol and I'll put in the URL of my application and v/s will go and look and I'll say oh yes I've seen that you've got a blazer application running side the browser there so let's do that shall we so I'll double click on this thing and v/s will say what kind of code would you like to debug and you'll say well I'll choose the only thing that you'll give them the option to so I don't know why asking me and then I'll choose ok and now es is connected to with the browser and so now I'm going to try putting a breakpoint on my c-sharp code here inside the IDE and then I'll type something in blue and then I'll click my button and we've paused Brewed bizarrely it says Visual Studio code but if I switch over here is actually hit the breakpoint inside my IDE so we've now got the IDE connected to the dotnet runtime running on web assembly inside the browser and we can actually debug ok so there's some things about debugging work right now but most of them don't as an example of something that does work we've got this very cool thing where we can show you the call stack that goes across different language types so if we look at the bottom you can see that when I click that button it's started by hitting it a javascript event inside component webassembly j/s that's how we know that the event happened it goes through various layers inside javascript it then goes through various layers inside webassembly before it finally lands on my c-sharp code so you can debug calls that go from c-sharp into JavaScript or from JavaScript back into c-sharp and you can step through the the chains of calls that go across languages like that so that works really nicely but most other things don't work we're working on it and we will get some nice debugging as we go forwards okay so that's where we're going next with debugging right can we make our applications start up any faster well isn't it fast enough for you already let's have a look okay let's go to my home page here and let's see how long it takes for my application to start so when I hit this button we can see that it does that sort of progress bar thing which is a bit weird but it is doing it and the reason why it takes about one second for it to start up is because this is the time where we're fetching mono and we're starting it up and we start on your application up and so we have to show a progress bar while that's happening but you may think you know what would be way cooler than a progress bar what the user would like to see instead of a progress bar the actual application if you don't mind that would be way cooler so how could we do that then well we've got these components right and they run on web assembly they run inside a browser and they don't out components and we've got a dotnet server so if you think about it couldn't we run these components on the server as well and then we could render the application on the server get its initial rendered HTML send that to the browser and then while the web assembly stuff is starting up the users already seeing the application UI that would be a lot better than a progress bar let's see if we can do that then so I'm gonna go over to the thing that defines my HTML okay you saw this in the browser earlier you saw this is where we've got this static HTML progress bar I do not want to see this progress bar anymore what I want to see instead of that is my actual application getting rendered so I can say all right then we're going to render a component asynchronously and the component I'm rendering is my entire application because remember components are everything your whole application is a component the pages of components layers governor's everything's a component and I've got a component called app which is the whole thing and that's what I want to render for whichever page you're currently on ok so let's see if this does its job correctly so now I'm going to press reload and let's see if we see a progress bar this time we do not see a progress bar that's a little better how fast is this thing starting up let's go to a new browser tab I'll put in the URL I'll hit go and boom my UI pause strangely there but let's try that one more time and then boom it's really quick okay no progress bar the application just comes up it's still an interactive application because we've loaded the web assembly stuff in the background okay and if you want to quantify how fast this stuff is really getting rendered on the server let's have a look inside the browser Network tab here and I'm going to hit reload again okay right then let's have a look you'll see that we are rendering that initial HTML there in 26 milliseconds so that is pretty fast that is a lot faster than that 1 or 2 seconds that we were waiting before and the actual overhead of rendering your razor components is really close to zero if you return a page that just returns HelloWorld is basically the same so the performance is really something I'm extremely happy with so that is doing server-side pre-rendering to make your application start up near instantly even while the web assembler stuff is loading in the background and one of the cool thing that you can do with that although I don't know maybe you'll think this is not cool but I kind of think it's cool in a sort of retro old-school way is what if we wanted to make a traditional server rendered application now we didn't want any of this web assembly stuff let's just delete that script tag completely what's going to happen now okay let's find out so I'm going to go to this weather forecast page here which is was already running when I hit reload it's not going to load any web assembly stuff at all now this is a pure server rendered application like a traditional MVC server-side application that just returns HTML to the browser if I look here it looks kind of disgusting so we haven't sorted out all the formatting yet but if you look closely this is the HTML markup that all the components are generating so it's a pure server rendered HTML application now and some parts of it still work for example any links HTML links still work so I can navigate backwards and forwards through this list but other things will not work for example my navigation menu will not work because that is built with an interactive component so if you wanted to you can use components for pure server-side rendering if you want but honestly that's not the best thing to do best thing is to make them be interactive as well okay right then last thing can we make our code run faster well is it not fast already how fast is it should we try and have a way of quantifying how fast our code is actually executing well that's why I've got this thing here called primes alright and we are going to be able to compute prime numbers all right let's get the tenth prime number that's twenty nine let's get the thousandth prime number okay that's have the ten thousandth prime number it's like a hundred thousand something and it's taken as three hundred and sixty milliseconds to compute that okay why did it take that long well let's have a look at the code for this I'm going to look at this component called Prime's and it's got this text field while you type in which prime you want it's got a button that's going to submit to this calculate method here and calculate is going to call a method on a library that I've written called super maths and that is maths not math for the Americans dot Prime's compute n Prime okay and if we look at the code inside that it's a very very brain-dead simple algorithm it's just going to do absolute brute force it's going to consider for all the numbers is it prime by checking all the possible divisors and then you know we're just going to keep doing that until we get to whichever one that you asked for very very simple and quite computationally expensive and we see that it takes about 350 milliseconds here now if we compare that in running it natively how fast is it going to be so to find out I've created a normal console app here called normal console app and if we look in the program main of that you'll see it calls the same thing it calls the same compute and the prime thing so let's set that as I start a project and run it and see how fast this stuff really should be okay it should be able to do this in like 12 or 13 milliseconds if it's running under JIT compiled native code and so it's not super honestly that it's taking 360 milliseconds we've got this slight factor of 20 or 30 slow down going on there and in fact it's significantly worse still if we go over into chrome let's see what it's like here in chrome world okay let's make sure I've got my application started up give me the ten thousandth prime please go and waiting oh okay so it's done it but it's taken a rather terrifying almost two seconds to do that why is it so slow then the reason this is so much slower is because when we're running your dotnet code on the mono web assembly runtime we're actually interpreting yet we're not yet compiling it because this is something that is extremely difficult to do under web assembly maybe we'll get there that's not what we're doing yet all right so this might seem kind of terrifying that we've got such a massive slowdown now as for how much of a problem this is it depends what kind of app you're building we've designed blazer to be able to produce really rich and sophisticated you is that up day faster than humans can perceive it even when you get to very complex you eyes so I'm reasonably confident that you can build something big and complex and your users are just going to regard it as being updating instantly because we've got this very optimized UI code path but if you want to do something CPU intensive obviously it's not such a rosy scenario but there are ways that we can make this better so what if instead of running on an interpreter we were able to compile your dotnet code to bare metal web assembly ahead of time and then execute that in the browser instead of running it through an interpreter and that is something that the mono team has been hard worker for quite a while and they're pretty close to being ready with this so I'm going to show you a little example right now this is just a proof of concept that's separate from what the mono team has done just to give you an idea of what the developer experience might be like so I'm going to look at my project file here for my app document that's the blazer application here and you can see that this is where we're referencing super maths and I'm going to put a little bit of extra instructions here to say when we reference that I don't want to load it as a dotnet diello I want to ahead of time compile it okay and then just because this is a hacky prototype I've put together I'm going to have to go to my index CS HTML and put in a reference for this other thing the a RT loader that that I've made all right so now when we compile this the application is going to be a little different because some of it is going to be ahead of time compiled so let's reload here inside the browser and I'm going to look inside the browser dev tools here because what I want you to see is that if we look in this framework directory with all the web assembly stuff we've not just got mono des awesome we've now also got super maths awesome where we've compiled the dotnet assembly to native bytecode and if I look at that okay so I have to refresh to see it but if i refresh then we look in there you can see this is the web assembly translation of our dotnet code and we've exported this function and compute F Prime and the implementation of it in just native web assembly has been generated right there okay but is it actually any faster shall we find out so let's say if I want the 10th prime well that's text in no time at all by the time we've got it running if we've that want the 10,000th Prime is it still going to take 300 milliseconds it now takes 1819 milliseconds so we've had a fantastic speed increase very very close to the 1314 milliseconds that we're getting running natively and in fact it's even better if we go over into Chrome and we try to get that one there so give me the ten thousands Prime and it's going to come back in ten milliseconds so it's actually faster than running natively now well not really okay that's this hugely misleading the most biggest way in which this is misleading is I'm running in debug mode here if I ran with release optimizations the native one would be a bit faster but not much faster so my point with this is not to say which one is faster out of web assembly or native the point is just to say that with a RT compilation it's completely reasonable for your dotnet code to run approximately the same speed or within the ballpark of the same speed of running natively so you can do super CPU intensive stuff if you want to though hopefully you don't even need to if you're just doing UI stuff ok so there is some stuff that is coming soon that we have not shipped yet okay so we're getting close to running out of time now I'm just going to give you a quick overview if you weren't down to talk this morning you saw this before these components that we're building their designs work in multiple environments so I've shown you these components running inside the browser on web assembly updating the Dom directly we've got a feature that's going to a spinet core 300 which is a you know a committed shipping production thing where you can run the same components that work under web assembly and you can execute them on the server in an interactive mode where all of the execution lives on the server and the browser doesn't see any web assembly at all and all the updates take place over a real-time WebSocket connection which is super if you want to make a very thin client so you've got low end devices that you want to run your components well you run them on the server and you just to push the UI updates over the channel it gives you access to the full dotnet runtime and could simplify your code in various ways it also has some drawbacks like you can't do this offline the client-side applications can work truly offline if you want them to but the ones that run on the server they can't because you know it's using the server to actually update the UI if you've also got the latency between the you know the browser and the server and you're using up your server resources but pros and cons and they're good for different scenarios the final thing the final case where you can run these components that's not client side or server side you might be thinking what hang on client side and server side that's the whole universe isn't it there's not there's no other side to this but there is another side to it which is what if you want to write a native desktop application with something like electron well you can run the same components there as well and we can update the applicant the UI directly inside electron it give you a very rapid example of that we did a little work exercise to try porting the Azure storage Explorer application to run inside blazer on electron so this is the Asha storage blacks pleura and it is a blazer the set of blazer components running inside electron so we've used the same web technologies that you see me use and we can make something that say you know looks and feels just like a native application we've got this grid with a hundred thousand rows in air we've got tabs we've got native right-click menus we can do network access we can interact with things like operating system services so for example let's see what Andrew nurse has been put into these blob stores open this item here and that's going to show up as a you know inside the native windows image editor so we can interact with the operating system properly from electron so point I've shown you all that is this component model that we're giving you now is designed to be incredibly flexible it can run under web assembly it can run on the server it can run on electron and your same UI components can work in all of those places so that is all I'm gonna have time to show you if you want to try out blazer I'd recommend you do surf there's a lot to learn we've got some documentation site there's lots of good community projects that are springing up around blazer and the whole a spinet core components system so you should go and try them out to do that you should go to blazer dotnet and that give you all the instructions about how to set things up and you can try that out and you know make yourself a happier and more productive person so that's all hope you enjoy the rest of the conference remember to evaluate this session [Applause]
Info
Channel: NDC Conferences
Views: 62,522
Rating: undefined out of 5
Keywords: Blazor, Web, .NET, JavaScript, Steve Sanderson, Web Assembly, UI Framework, ASP.NET, .NET Apps, SPA Frameworks, DI System, NDC, London, 2019
Id: 0RfUPr0KrSM
Channel Id: undefined
Length: 60min 45sec (3645 seconds)
Published: Fri Mar 29 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.