Was I Wrong About Blazor? | Coding Shorts 111

Brief Summary

Shawn Wildermuth explores Blazor WebAssembly (wasm) to determine if his previous reservations about it were justified. He examines a client-side Blazor application, discussing its structure, the use of C# for web development, and the performance implications. He concludes that Blazor wasm is a viable option, especially for developers familiar with the Microsoft ecosystem, but notes some tooling and optimization challenges compared to traditional JavaScript frameworks.

  • Blazor wasm allows building client-side web applications using C# instead of JavaScript.
  • The framework leverages web assembly to execute .NET code in the browser.
  • While Blazor offers a familiar environment for .NET developers, it has tooling and optimization challenges.

Introduction

Shawn Wildermuth introduces the topic of Blazor, reflecting on his past opinions and deciding to re-evaluate it, particularly the client-side web assembly (wasm) aspect. He mentions his upcoming workshop on asp.net core architecture. He expresses initial skepticism towards Blazor's early server-side rendering approach using SignalR, but acknowledges the shift towards web assembly for client-side development.

The Project

Shawn demonstrates a simple Blazor project in Visual Studio, emphasizing that it's a client-side application without server-side components. He highlights his experience in building similar websites using JavaScript and TypeScript, and aims to compare that experience with using C# in Blazor. The application calls rest services to function.

Project.cs

Shawn explains the structure of the Blazor project, starting with Program.cs, which sets up the application. The root component, "app," is added and mounted to an HTML element with the ID "app," defined in index.html within the wwwroot folder. This setup is similar to other Single Page Application (SPA) frameworks, where markup is built inside code and mounted into an HTML object. The project uses services to build up different components, connecting to an API in Azure and instantiating a client to use it.

App.cs

The "app" class contains markup that defines the application's structure. It uses a route view to handle routing, similar to view. The class includes a "not found" page for unmatched routes. Components like layout view and page title are C# classes.

Open Web?

The layout uses razor syntax to inject the page body. Tailwind CSS is used for styling, integrated through npm and post CSS. The task Runner Explorer extension runs Tailwind in the background, with bindings set to run when the project is opened. The build process is similar to other asp.net core projects.

Pages

Shawn discusses the pages within the Blazor application, noting that while many pages consist of markup, it's common to include code blocks as well. He prefers keeping code in a separate class for testability. He shows the homepage with razor syntax for conditional rendering and data binding.

State

Shawn addresses state management, explaining how to share state across different components. He uses a simple class, "app State," injected into the service collection to ensure all components receive the same instance. This class manages lists of films and years, with methods for loading data and updating the state.

Data Binding

The "app State" object is injected into pages, allowing data binding to populate elements like select dropdowns with data. The state object provides options for years, and film data is displayed using components.

Components

Shawn introduces the "film view" component, a thin razor page with markup defining the film's appearance. This component is used to display film information in a consistent manner across the application.

Under the Covers

When running the application, a message indicates that linking tree shaking is disabled, resulting in a larger application size during development. The core of Blazor wasm is the blazor.webassembly.js file. The build output includes .net js, Blazor js, and wasm files. The framework loads wasm files, and the size of the application is larger due to the lack of tree shaking. Web assembly is central to Blazor, but initially, only the framework and CLR were wasm, with other components loaded from dlls.

Wrapping It Up

Shawn concludes by revisiting his initial question about Blazor. He acknowledges that his opinions have evolved with new information. While he might not use Blazor for all web applications, he sees its value for developers accustomed to the Microsoft ecosystem or those needing to build web applications without extensive JavaScript knowledge. He notes tooling issues, such as the need to restart the project frequently, and concerns about optimizing web experiences due to the black-box nature of Blazor wasm. He suggests that Blazor wasm needs further polishing, particularly in the JavaScript wasm bridge. He believes wasm is more beneficial for tool vendors needing efficient memory management. Despite his reservations, he encourages discussion and acknowledges that Blazor meets specific needs, especially for organizations within the Microsoft ecosystem.

Summarize any YouTube video in seconds

Get summaries like this one for any video, in your language, with the free Summ app.

Download on the Apple Store
Get it on Google Play

Transcript

Full transcript of “Was I Wrong About Blazor? | Coding Shorts 111”. Click a timestamp to open the video at that moment. Need another video? Use the YouTube transcript generator.

0:00 welcome back to coding shorts my name is Sean Werth today I want to talk about Blazer a lot of people have been asking me about blazer for the last seven years that it's been out and I've had opinions all across the way but it got me thinking maybe I'm wrong about Blazer so I thought I'd give it another shot but before I dive in I did want to just plug my upcoming one-day workshop on asp.net core architecture you can see the link here to go get your tickets it's on November 11th and I hope to see you there so Blazer's kind of intrigued me from the beginning in that it attempted to do some things serers side that I thought were interesting but they seem so not web standard-ish was using signal R and a server and serers side rendering and all of that was great and if you know me by now you know that I'm not a

0:46 huge fan of server side rendering Le you have a really good reason for it but as time went on they really embraced web assembly as a way to build client side code as well and I hadn't looked at that in a couple of years so I thought I'd dive in and talk about Blazer waza not the whole ecosystem not the server side but just the client side C that you can write today to build websites let's take a [Music] look I'm in visual studio with a simple Blazer project and I'm just going to run it just so we can see what we're actually using I'm not going to be building a brand new project with blazer in front of you cuz that would be a whole course but I did want to sort of highlight some things that I found pretty interesting interesting and I've written this sort of website in

1:32 JavaScript and typescript for years and years now and I wanted to see what that experience was like in using C this is a website running all on the client there's no server components here at all to build a client side application that happen to call in my case rest services so let's take a look at how this is really structured obviously program.cs is going to do and this is part of the boiler plate to sort of set up your application this root component wants to add a object called app that's actually in this app. Riser class and it wants to mount it to what this is a CSS selector to find an element so where does this come in if we look at ww root we'll see that there is an index.html again this is mostly The Boro plate that they ship with and they have an element called ID

2:18 app they have a progress bar until it's loaded but you're not going to see that very often more importantly it's going to replace everything that's inside of this ID app with your Blazer components and so of the gate this feels very much like any other Spa I'm going to build some markup inside of code I'm going to mount it into an HTML object and we're fine because this essentially asp.net core we can see that we're using services to build up different services that we want I have used connected services to point at an API that I can use so I'm not actually running any server side code here I'm actually calling an API that I have out in Azure and because of that I'm instantiating an instance of that client so I can can use it in some places and we'll come back to what app state is so let's walk what this actually looks like so remember

3:05 we're going to be instantiating an app and the app class contains markup and this markup is trying to tell it different conventions about what it needs to show so the found here is going to create a route View and if you've done anything in view especially it should look very familiar and it's just going to say where it's going to get through route data and what it's going to use as the default layout really simple straightforward Spa like conventions it happens to have not found so if it can't find a class that matches it shows this very simple page we can see that these components layout view page title etc those are all just C components they're C classes we'll see how to use one in a minute and so let's talk about how the layout works first and again if you've done any Spa this

3:51 should be pretty comfortable and the M layout is where we start to look and see pure HTML in some sense so it's just using a razor convention here to say this is where the body or the page should be injected you might have a lot more on this page that isn't necessarily just a div container you might put a menu on the top and all sorts of things like that I chose to keep it nice and simple and if you're paying attention you might have noticed this lovely piece of text this is styling of our application and if you recognize this then you have used Tailwind before Tailwind or any other component Library you want to use is still just client side code in some respects if we look at the side view here you'll see that I have a Tailwind config and that I have post CSS and then inside my package I've

4:38 done very common web sort of things now because this package didn't exist with the standard because the standard isn't going to necessarily use tools I had to go ahead and initialize this with npm a nit and then go ahead and add the dependencies just like I always would and so I'm literally building the Tailwind as I write this code and so I can use the same layout semantics I'm comfortable with these can be used anywhere in the application and so since I have Tailwind here how am I running it I'm actually using an extension called the task Runner Explorer and this will be running it in the background the whole time I'm writing this app what's interesting here is I have bindings and what have I done I've packaged this event in the package that Jason to when the project is open so this is just

5:23 running the whole time as soon as I open Visual Studio you can imagine doing this before build after build or maybe even doing something different on a clean but for the most part that's the case just like any other asp.net core project I can go ahead and do things like run the actual build before I publish so later we're going to be looking at publishing briefly just so you can see how that works so I'm not going to dive too far into it but here I have just two pages just so like we saw before and while a lot of pages will just be markup and you'll see that with the razor extension it's also pretty common to see code blocks in there as well but of course me being somewhat of a purist I want those in a class behind that I can actually run tests against and such so here I have a simple homepage and the razor

6:09 syntax that I'm used to from years and years ago continues to work so I can say you know if there's an error message show this up top otherwise go ahead and create that select based on some data and you're going to see at bind used a couple of times to figure out how to show that current year and how to fill it in with the data from the years we start to look at the magic State object now what the heck is that state object if we come back into the home here we're actually injecting this app State object into both of our Pages you'll see it here on the details page and on the homepage because one of the things that's not obvious is how do you share State across the different pieces and I've chosen a way that feels and looks a lot like the way I manage State inside view application so I've created a

6:54 really simple class it's not doing anything magical I'm sure there's some third party pack that maybe makes this easier but this is just an instance of a class that I'm injecting into the service collection so that anyone who asks for it gets the same instance of this and you can see here we have a list of films we can bind two we have a list of years and then some methods for loading the year values loading a single year of films or loading all the films and when it does this it just changes its own state so that back here in the code I can say oh you know what when we start go ahead and load those years so I can bind them to the data and so what happens to this this actually fills the years that we're bound to here so I can say state which is that state object do years go ahead and show me options for

7:41 each one of those and in the same way if there are any films shown then walk through this and go ahead and show these and in film view you're going to see very much the same idea film view is a component so if we head over to film view this is just a thin razor page I've got a tiny bit of code which I could have put in a code behind class but because we want this to be nice and small and simple this is just the markup that makes up what the film looks like and so I can change it in one place and use it in a bunch of others and so what I find interesting here is that when we run this when we look at the console in the web you actually see this little net message that says this was built with linking tree shaking disabled so your application is going to be a lot bigger during development and that shouldn't be any surprise to you we'll actually see what this looks like at the end of it

8:27 and it all starts with this blazer. web ass .js that's in your project and so if we come back here you actually see inside the build itself is going to be a net JS you're going to get a Blazer JS usually as well and all the way at the bottom because I called it a w you're going to get a Blazer D you're going to get a wrong about Blazer dll the name of the project and so for the most part these are being loaded up by a so if I open up the bin and look at I'm using net 9 here that would be pretty much the same with net 8 and I look at the WW rot these are artifacts from the build we actually want to look at what is deployed out there which is WW root and so this has all sorts of code in here you might notice that these names correspond to assemblies inside of the framework code right collections

9:13 component model and then all the way at the bottom here we're going to see actually a wrong about Blazer WM and all of these are WM files so it's actually building and deploying actual WM to your application now this will end up being bigger than you probably imagine it because it hasn't done in any tree shaking and some of these may go away but this is going to be much bigger so this tells me something that web assembly is at the heart of all of this one of my complaints earlier on with the way that Blazer and wasm worked was that you really only getting wasm of the framework and the net CLR everything else was being loaded from dlls that nothing was going to be compiled early it was all going to be quite slow to start up and even on our development machine we can see that we have that weight cursor but it goes through really

9:59 quickly and I think we'll see in a minute how quickly it can actually get let's go ahead and publish this real quick and I have this publish I'm going to tell it to go to a folder instead of some magical place and I'm just going to say go to my desktop and I'll put it in a folder called wrong let's go ahead and cause it to publish when we look at this the publish itself is doing a lot more work than the simple publishing you may see from net unless you have something like aot turned on and that's because it's doing a lot of work to basically tree Shake all the things you don't need to make make your application as small as possible in the middle of this you're also seeing that I am building that CSS file and it finished you can see it took about a minute and a half I've sped it up so you didn't have to sit here with me and let's go ahead and look at that project so I'm going to say users Sean

10:46 desktop wrong so you can see a few pieces here and this is mostly about how it's hosted but all the magic is in that ww route you'll see that we have the index it can actually send these pre-compressed instead of compressing them on the Fly there's my magic CSS which of course has also pre-compressed that's sort of the ways it's trying to make it faster and then underscore framework is where all the magic happens so we can see a Blazer web assembly and this is the thing that loads everything and we can actually see a Blazer boot. Json so I'm going to open this with Studio code and all this is is a list of all the different wasm files that they're going to need and so this is pulling them in one at a time and that's part of what the Blazer file actually does and so for we go ahead and just say light server which is a very light HTTP

11:33 server that I have for testing these things we can see this is running and if we refresh it we do see that loading screen but it's so much faster and this is mostly because we're running the actual application and so the size of this becomes interesting I know I'm getting a little bit in the weeds with this but I think that's okay so if I look it wrong let's look at how big it is so about 22.5 Meg could be smaller this application is also small so that can balloon quite a bit depending on how much C code you have but if we do the same thing for our Ben let's see how it is before we publish 62 so significantly smaller so that really leaves me at the particular question was I wrong about Blazer now if you haven't heard my opinions about Blazer over the years it's going to be hard to know whether I was wrong or

12:19 right I change my opinions as I get new information so was I wrong probably at some point but is this the way I would develop all my web applications probably not I really feel like like Blazer has been built especially blazer wasm for people who need to use the web that are used to maybe even server side or only desktop applications or even just backend developers that need to build an application but they don't have the time the energy or maybe the interest in learning how JavaScript typescript and web front ends actually work and so this becomes a quite easy way to handle it problem I have with it and why I probably wouldn't do it is the tooling is pretty iffy right now the idea of of being able to change the markup the razor files and have it shown in the browser simply doesn't work right now I

13:05 spend a lot of my time restarting the project which can be a bit frustrating another reason I'm a little shy about Blazer and I'm sure they're going to make it better maybe this will go away but there are a lot of tried and true methods for optimizing your web experiences because this is sort of a black box that you're deploying to a web server things like breaking things up into smaller packages as they're downloaded or downloading on demand optimizing images handling a lot of that stuff that really requires events from the Dom into some code there's still some Plumbing between wasm and JavaScript that I think is going to make that a little bit more difficult this is more about how I want to deploy applications and want to have control over how they're loaded how they're built and such I just don't think even

13:50 though it's 7 years old now Blazer WM isn't 7 years old I had trouble finding when it was actually released but I think it's closer to 3 or 4 years and I think it needs some more time for them to polish it up and part of this polish up isn't that there's anything wrong with blazer as is it really comes down to the JavaScript wasm Bridge can be difficult and we're doing a lot of logic in the wasm and I think wasm is really more beneficial to people like tool vendors people who need to deal with memory on a larger scale need to be able to scan and build memory objects in an efficient way a lot of the things we're doing here would be as easy were often easier than it would just to write the JavaScript or typescript but that's just my opinion I'm only coming from sort of my muted view so I've been in C for a

14:38 long time and I wish that the benefits of one language on both sides would magically be great I ran into this with node having the same language on both sides but I still feel like most of the projects I'm going to develop are going to be using new Frameworks on the front end and then using asp.net and C on the back end please let's have a discussion in the comments I know that a lot of you are either rage watching this now or or this is just validation what you really sort of believed in your gut maybe not with the data and I suspect that both of you are wrong like this is just another tool and I think it meets some really good needs if you have a small organization or even a large organization that doesn't have anything outside the Microsoft ecosystem and needs to stand up an Enterprise app or

15:24 an internal app I think this does a great job it'll do a good enough job when you starting to building larger and larger pieces of componentized frontend code I'm not sure this is the best solution so I want to know what you think please let me know down in the comments if you've gotten this far I appreciate you coming and watching my videos I'll put another quick plugin for my workshop on November 11th pragmatic architecture for asp.net core you can see the link here where to register it's a one day event and I think you can get a lot out of it also like And subscribe I know I'm supposed to say that more often and more in the front but in really does help me and I really appreciate that I've been able to over the last couple of years build this channel from 2 or 3,000 that was mostly just my friends and family that were looking at pictures of my wedding to 17

16:10 18,000 whatever it's at now still a small Channel but I feel good about how it's growing and every one of you Watchers is responsible for that I'll see you next time on coding shorts my name is Sean Wilder meth [Music]

Share

More video summaries