OdeToCode IC Logo

The Blazor Bet

Tuesday, September 24, 2019

Today's release of .NET Core 3 is significant. By supporting Windows desktop development and dropping support for the full .NET framework, v3 makes a statement - not only is .NET Core here to stay, but .NET Core is the future of .NET.

Included in all the fanfare is Microsoft's new web UI framework by the name of Blazor. Blazor gives us the ability to write interactive UIs using C# instead of JavaScript and it works using one of two different strategies. The first strategy compiles C# code into WebAssembly for execution directly in the browser. This WebAssembly strategy is still experimental and won't see a supported release until next year.

The second strategy sends client events to the server using SignalR. C# code executes on the server and produces UI diffs, which the framework sends back to the client over SignalR for merging into the DOM.

Server-side Blazor

Most people won't see much risk in moving to .NET Core these days. Blazor, on the other hand, doesn't have a clear path to success.

Out of the Frying Pan

Client-side development is a subjective experience. There are developers who embrace the organic JavaScript ecosystem. There are also developers who are desperate to see Blazor succeed because the messiness of working with disparate package managers, compilers, and frameworks du jour is raw and frustrating. These individuals don't necessarily dislike JavaScript, but they do feel vastly more comfortable and productive using a language like C# and tools designed to work seemlessly end to end.

These developers typically stick to building applications using server-rendered HTML because the environment is simple and productive. Yes, there is always a push to be more interactive, depending on the type of application being built, but sometimes a well-placed JS component will work well enough and avoid the complexities of building a full blown SPA.

For these teams that have avoided the Angulars, Reacts, and Vues – is now the time to jump into client UI using Blazor?

Typical Blazor App

And into the Fire

One of the first arguments against Blazor is the "look what happened to Silverlight" argument, a reference to Microsoft's last successful client UI framework. A framework Microsoft killed just as the framework was reaching peak popularity.

I personally don't consider what happened with Silverlight to have any impact on the decision to use Blazor, or not. I say this partly because Microsoft is a different company today compared to 10 years ago, but also because every Microsoft product and framework faces the same risk. Microsoft will always be inventing frameworks, then promoting and evangelizing those frameworks as the solution to all software problems. Microsoft will continue investing in those frameworks until one day, something better comes along, and suddenly, with no fanfare or formal announcement, you'll find the framework dead on the vine.

This isn't just Microsoft's history for decades, but a chronic condition of the software industry. Ask WCF customers.

The bigger risk, I think, is in the execution strategies. The WebAssembly approach, where code executes in the browser, is the solution we want to see working, but WASM is still in preview because of technical issues. When the WASM approach does arrive, we still need to evaluate how well the approach works. How much does the browser need to download? How good is DOM interop from C# code? How will the compiler work with all the evolving interfaces of the W3C? Will the development experience be as iterative as today's hot-reload experience? There's many questions to answer.

Blazor and WASM

With WebAssembly on hold, we are left with the server-side execution model. But, there's something about this model that doesn't pass a sniff test. We've been told over the years that stateful web applications are evil. We've been told over the years that the network is slow, unreliable, and not to be trusted. Suddenly, Blazor enters the room and talks about storing state on the server and running click events over the network. The mind explodes with questions. Does this even scale? Can it be trusted? What happens to my mobile users in a train tunnel?

Everything about this first version is wrapped in caution tape. Everyone wants to make a prototype to see how it works. Nobody is ready to bet the farm.

Consider Issue Number 12245

Remove stateful prerendering is an innocuous title, but the implications for Blazor are considerable.

To summarize the issue – each Blazor component requires some space on the server. If you request too many components, the server can run out of space. Thus, malicious users can leverage Blazor to DOS your servers.

Issue 12245 is the type of issue that comes to mind when "run client logic on the server" is listed as a Blazor feature. How can there not be issues with security and scale?

Like with many security problems, the solution is to eliminate a useful feature. Now, you can't use Blazor to render a component that depends on a piece of state or a parameter. The only state the component can use is state the component creates once the component connects to the server.

Unfortunately, the solution eliminates many component use cases. Let's say I don't want to build a SPA. I want to add interactivity to specific pages in an app. To do so, I'll create components that can render an account by ID, or show the score for games on a specific date. With stateful prerendering it was easy to pass an ID or a date to a component and let the component go out and fetch whatever data it needs.

No stateful prerendering means there is no direct mechanism for passing parameters to a component. Components will need to dig parameters out of a URL, or use JSInterop to fetch parameters from state embedded in a page. Although both are possible, it does make some component scenarios impossible, and almost all scenarios become a bit more hacky.

Summary

In the end, I believe WebAssembly is the model we want to use with Blazor. I'm curious to see if the server-side model, with it's inherent limitations, will continue to live once WebAssembly arrives. The server model will probably be easier for developers to use, but we can already see how limitations will hinder widespread adoption.


Comments
Gravatar Bart Wednesday, September 25, 2019
Hi Scott, I think the primary use case for server-side blazor apps is currently non-public facing websites. Such as internal company sites. In my opinion server-side blazor is actually quite a good choice for such niche apps because it keeps the site deceptively simple (akin to a current MVC or razor pages app) while feeling as responsive as a javascript SPA. The relative simplicity (no need to bet the farm) and the ability to share component libraries are both attractive in that scenario. They would also be attractive in public facing websites. But I agree with your assessment that server-side blazor doesn't scale. Microsoft itself mentions this as well in its description of server-side blazor user cases.
Gravatar GG Wednesday, September 25, 2019
Nice summary of the current trade-off-set. Agree with Bart. I think that initial load-time is the primary challenge that the client-blazor/WASM is trying to fix before releasing. We have our finger's confidently crossed. Also, I think a hybrid scenario could enable developers to make their own choices about which blazor-model to use at different places in a system. This would be similar to the "well placed JS component" approach you mention above. This "hybrid" approach may be more complex than meets the eye. I saw this: https://stackoverflow.com/questions/57937635/blazor-net-combine-server-side-blazor-with-some-offline-pages-razor-or-blazor
Gravatar John DeHope Wednesday, September 25, 2019
"...internal company sites ... such niche apps... " It's a pretty cozy niche though! Almost every app I've ever built, for every job I've ever had, was a "line of business" app for an internal business intranet. It's a fantastic space to work in. Highly recommended. There is no technical reason to compile the C# code to .net bytecode, and then ship a wasm .net virtual machine over to the client. It's going to take a lot of humility and willingness to risk throwing the baby out with the bathwater at Microsoft for them to compile the C# code directly to just plain wasm. But it's okay, they will do it, because "Microsoft is a different company today compared to 10 years ago". Any particular .net virtual machine, even the .net IL, is bathwater not the baby. The baby is C# and the .net standard library and access to a sea of nuget packages. They will be able to deliver those things by compiling everything to wasm and shipping that to the client. It will be beautiful. It will still be .net!
Gravatar Mister Magoo Wednesday, September 25, 2019
GG - I'm not finding an issue particularly with initial load time - my Blazor WASM application scores 100% in the Chrome Lighthouse test - sure it could be a bit faster to load (about 1.3s on a wired connection), but my app relies on data from a third party, which is the real bottleneck, so I have to say 100% happy with webassembly based Blazor so far.
Gravatar Michael Washington Wednesday, September 25, 2019
To see a publicly facing server side Blazor site you can see: https://razor.radzen.com/
Gravatar Mo Wednesday, September 25, 2019
The client side blazor is the model I am waiting for too. Most PCs now come with minimum 8 gig of ram and fantastic gpu and cpu power so why not put the client logic run there and take load off the server. Also consumers are spending $1300 on mobile devices so they do demand interactivity and offline capabilities.
Gravatar Abdu Wednesday, September 25, 2019
Many sites have images on the home page that total in size more than the whole WASM runtime. A couple of seconds extra to load it during the first hit in this era of broadband and soom 5G on mobile is nothing. Plus the runtime will be cacahed. Microsoft is still optimizing the size and they did a fantastic job so far. Use Blazor (server side or client) in the scenarios that fit the job. It's not meant to replace Javascript but for some individuals and companies it might as well will.
Gravatar Tom Redox Wednesday, September 25, 2019
The Blazor team are looking to try and get the facility to pass parameters to server side Blazor components working again in the 3.1 release, it's now detailed in the new case 14433.
Gravatar Ektoras Wednesday, September 25, 2019
Server side blazor does not really solve a problem or fills a gap. But client side is game changing. It works with w3c standards (wasm) and open source (dotnetcore), so it cant be compared with silverlight. And if someone prefers javascript from c# or writing the model on the server side and again on the client can ignore blazor. For the others dotnet over wasm, maybe in another form than blazor, is the future.
Edo Wednesday, September 25, 2019
Every criticism posted here, is a criticism against modern web apps in general. What was the last web button you clicked, that did not require server operations? it is all ajax dynamic operations as far as the eye can see, and it is only going to get more like that
Gravatar Fallon Thursday, September 26, 2019
Blazor(Webassembly version), IMO, is a framework in search of an identity. Comparisons to Silverlight are not accurate for several reasons, mainly because on the political side, unlike Silverlight, MS doesn't need Apple or Browser makers to cooperate(a plus). On the technical side, and a huge minus, is that unlike Silverlight, the runtime is NOT packaged and cached on the client, it has to be downloaded most times, if not all. That being the case, Blazor, unlike C/C++, Rust and others, which can position themselves as either a compliment to javascript or a replacement, Blazor is mainly positioned as a replacement because it's runtime is too big to be a compliment. There are obviously a lot of use cases for paying the download penalty for Blazor, but not likely in reach application, most likely LOB apps. Server side Blazor is ok, but it's not really why we all fell in love with Blazor in the first place. I'm not sure what to make of Blazor anymore, and I'm also not sure how they plan to mitigate the large runtime download issue. I guess we're in a waiting pattern...
Gravatar Randy Thursday, September 26, 2019
I agree with everything you said, but I view most of it as simple common sense. Betting the farm on a v1.0 of any software technology is a gamble at best and utter foolishness at worst. I am not javascript hater, but I would certainly be happy to be able to use C# for both front and backend. I will cheer on Blazor and hope for it's success, but I won't be rushing to create any large Blazor production apps just yet.
Gravatar Robert Swilley Thursday, September 26, 2019
Scott, You said Microsoft killed Silverlight just as it was reaching peak popularity. This isn't entirely true. Silverlight was killed after the release of the iPhone and the rise of HTML5. The browser plugin model died, so Microsoft had no choice but to kill Silverlight. Flash was a victim as well. Silverlight is reaching end of support on October 12, 2021. I was never a big fan of the browser plugin model. I've never done any Silverlight work, but your comment makes it seem like Microsoft just killed Silverlight for no reason.
Gravatar scott Thursday, September 26, 2019
@Robert: But it was Microsoft's decision to kill Silverlight. We have all sorts of stuff running in the browser today with no plugins. Where there is a will, there is a way,
Gravatar Steve Buchok Thursday, September 26, 2019
Blazor files (mono.wasm and any DLLs) are cached client side just like any JS/CSS files are. Also, JS interop in Blazor is very easy to use. I have been using Blazor now for about a year (Since 0.4.0) and for the most part, it is a replacement for most things that I used to use JS for. However, I have needed JS for a few things and it was very easy to use JS along side Blazor. My entire app that I've been working on is only about 4MB which is only slightly larger than double the size of this one page (my app has about 30 pages and has two extra fonts and some other stuff that I could probably remove to make it smaller). They also still have plans to reduce the file size more. Right now, the base download size is about 2MB (mono.wasm and DLLs for from scratch project), which I don't think is terrible but could be better.
Gravatar Robert Swilley Thursday, September 26, 2019
@Scott At the end of the day open web standards won. Silverlight and other plugins lost. I’m not sure what Microsoft could have done? This is why we have typescript now and blazor client side in the pipe right? We can’t predict the future. All technologies have a shelf life. Any technology can be killed. I’d like to have a choice what language I write in the browser. I’ve been using JavaScript for many years, but I’m sick of the framework churn. I guess we will have to see how everything plays out. I’m curious is your opinion to continue writing front end apps in the JavaScript framework flavor of the month? I believe you said recently in one of your recent posts that you had stepped away from the front end in part due to the churn. You mentioned upgrading to the new version of webpack and having a broken app due to no backward compatibility as an example. Anyway I enjoy reading your thoughts!
Gravatar Dennis Landi Friday, September 27, 2019
Thank you, Scott. I will continue to watch the Blazor space as client-side comes to fruition. In the meantime, I am quite happy to click bloated javascript frameworks to the curb in favor of Razor Pages in a ASP.NET Core App. (Yes, I've taken your pluralsight courses on that topic). And, as I understand it, my existing Razor Pages should port right over to Blazor (if and when the time comes.) -dennis
Gravatar Fallon Friday, September 27, 2019
@Steve Buchok - I ran some tests on the Uno platform and Blazor, and it appears that you're correct, the dll's, etc., are cached like any other browser resource, so the majority of the hit will be on first load. This is good news, and any effort to further minimize the size will only make it better. I'm not a JS hater, but as a once strong Silverlight developer, I know and understand the strengths and limitations of both, so I'm inclined to use the best tool for the job. Thanks for clearing that up!
Gravatar dbjdbj Sunday, September 29, 2019
Good, sober article. Architectural issues explained. I see this picture from afar: This whole Longhorn / .NET / C# "Gilgamesh" has been put in the "public domain" ... The synonym is probably: "orphaned". Which does not mean you can not earn a pension on it. Respect.
Gravatar Steve Bishop Tuesday, October 1, 2019
Microsoft could put the Mono runtime in Edge and eliminate the load complaint, or the .NET Core installer could come with it, but then we're back to a plugin model. I don't think any team working on a WASM solution with a higher level language is going to be able to get around the problem of uploading a sizable runtime to the client without significantly limiting the features.
FJ Friday, October 4, 2019
It all sounds very WebForms #2 to me ...
Gravatar Daniel Roth Tuesday, October 8, 2019
Hi folks! I'm Daniel Roth, the Program Manager for Blazor at Microsoft. Thanks Scott for writing about Blazor! I thought I’d share some details about the scale characteristics of Blazor Server to help folks evaluating the technology. Blazor Server is supported at scale for everything from internal line of business apps to large public facing sites. The scale characteristics of Blazor Server are of course very different than a traditional single-page app, which offloads much of the work to the client. Blazor Server apps instead handle the UI for all clients on the server. This does mean more server resources are required to run Blazor Server apps. But it does not mean that Blazor Server apps cannot handle significant load with a reasonable amount of server resources. While .NET Core 3.0 was still in preview we tested Blazor Server to see what its baseline scale characteristics look like. We put a Blazor Server app under load with active clients simulating normal usage and monitored the latency of the user interactions. In our tests, a single Standard_D1_v2 instance on Azure (1 vCPU, 3.5 GB memory) could handle over 5000 concurrent users without any degradation in latency. A Standard_D3_V2 instance (4 vCPU, 14GB memory) supported well over 20,000 concurrent clients. The main bottleneck for handling further load was available memory. Will you see this level of scale in your own app? That will depend in large part on how much additional memory your app requires per user. But for many apps, we believe this level of scale out is quite reasonable. We also plan to post additional updates on improvements in Blazor Server scalability in the weeks ahead. So stay tuned!
Gravatar Daniel Roth Tuesday, October 8, 2019
Also, support for stateful prerendering was removed from .NET Core 3.0 due to specific security concerns with how the feature was implemented. This was part of our normal engineering process to ensure we are shipping secure software. Support for passing parameters to components during prerendering is coming back in .NET Core 3.1 later this year.
Gravatar Daniel Roth Tuesday, October 8, 2019
For folks interested in answers to the questions posed here about Blazor WebAssembly: Q. How much does the browser need to download? A. Blazor WebAssembly apps currently weigh in at ~2.4MB compressed. The bulk of that size comes from the WebAssembly based .NET runtime (~850KB compressed) and the core system libraries. By comparison, the default app assembly is very small (<10KB). While we believe the current download size tolerable for many apps, we are still working on further reducing the size of the runtime before we ship. We already support removing unneeded code from the app using a .NET IL linker, and the files can be cached using standard HTTP caching. You can also prerender the app on the server to hide the cost of the initial download. || Q. How good is DOM interop from C# code? A. Blazor apps don't typically interact with the DOM directly. Instead you write rendering logic with Razor components and let the Blazor framework intelligently update the DOM for you. Blazor will track what each component renders, compare the output with what was rendered previously, and then update the DOM with just the changes. This makes rendering in Blazor very efficient. In cases where you do want to interact with the DOM directly, or interop with JS, you can use the JS interop APIs to call any JS you'd like from your .NET code. || Q. How will the compiler work with all the evolving interfaces of the W3C? A. Because of the way rendering and JS in Blazor works, Blazor is in general not affected by additions to the browser APIs. Newly added APIs can be called through the existing JS interop mechanism. || Q. Will the development experience be as iterative as today's hot-reload experience? A. We actually don't have a great hot-reload experience with Blazor today. The current experience uses a file watcher to detect when code has changed and then automatically shuts down the app, rebuilds it, and starts it again. Instead we want the ability to apply app changes to the running app so that you can iterate fast. This is a major area of investment for .NET 5. In the meantime, Blazor WebAssembly will support the current auto-rebuild functionality. I hope this helps!
Gravatar Jimi Friis Friday, October 18, 2019
Thank you Scott for a great article! and a Huge thank you Daniel Roth for the clear Questions and Answers. //Jimi
Gravatar Raphaël Sunday, October 27, 2019
Hi Folks, I’ve been playing with Blazor (SSB) since its early previews, and I’m very optimistic about this technology. The learning curve is far less than Angular, and reminds me the ease of window development, I especially appreciate the fact of not having to care about client-side development, so we can focus more about the app business logic. In the company I work for I’m currently developing an e-Commerce website, and performance using a async programming is just incredible compared to MVC 4. And you can also take advantage of modern programming goodies, such as generics, async programming, the ability of easy component development, easy event wiring... So far so good...
Your Comment