Corrupted Teams chats after forced reboot Handling dates in single-page applications

Thoughts on Microsoft, and Blazor

Published on Friday, July 2, 2021 5:00:00 AM UTC in Personal & Philosophical & Programming

After I started working with .NET in 2001, software development turned into a real passion for me, to the point of becoming an obsession sometimes. Compared with the previous struggles of desktop programming with C++ (MFC anyone?) and web programming with Perl, for many years every next iteration felt so fascinatingly easy and modern and productive. Technologies like WPF almost seemed like something unreal from the future to us, and every new release of .NET brought a new wave of even greater enthusiasm and motivation. When Silverlight came out I was so convinced by its capabilities that I put all my energy into pushing it as much as I can, spent hour after hour learning every possible detail, and climbed to the top 3 of global contributors in the official support platforms. With my equally excessive excitement for Windows Phone, I became a Microsoft MVP.

shirt-microsoft-dot-net-2001-cropped-small.jpg

Proudly worn shirt from the early 2000s

Then, things began to crumble, slowly at first, but then collapsed. Today I would consider myself a Microsoft sceptic, although I heavily use and promote Microsoft technology almost every day. What happened? Actually, a lot of things, starting with the demise of Silverlight. That of course wasn't really Microsoft's fault. And even though friends, colleagues and I perceived more and more decisions around Windows Phone as increasingly worse moves in the wrong direction (it's easy to judge from the outside, isn't it), you cannot blame anyone in particular for its failure either. Trying to gain a foothold in mobile business wasn't a particular easy task, very risky and likely to fail. But over the years, many of those questionable and, to me, disappointing developments followed, and made me think. I perceived Windows 8, for example, as a total disaster, and so I felt about most new developer technologies that came with it or in later incarnations, like Windows Runtime or UWP in Windows 10. The overwhelming parts of new developer-related features that were released during the past years just seem like a wavering course without a clear goal, without a vision, without consistency. Even really promising new technologies like .NET Core went on and on for years like this. Oh, the hours lost learning project.json, just to then move everything back to .csproj! Do you remember the painful hell that retrofitting .NET Standard into .NET 4.6.1 caused? Just three words: System. Net. Http. My nightmares wasn't Pennywise or Freddy Kruger, but binding redirects. And once you finally had a deep understanding of the concepts behind .NET Standard, the subtle differences of its implementations, the monikers involved, someone went wreak havoc and brought us .NET 5, to reunite all worlds (this time for real(!?)) and make .NET Standard obsolete. Everything old is new again.

Another example: what's the story around UI technologies? UWP, WinUI, XAML Islands, Xamarin, WPF, Winforms, .NET MAUI, Blazor Desktop? I know I'm mixing Apples and Oranges here, but that's what you're confronted with when you want to learn the moving parts of UI technologies from Microsoft: a huge, ugly mess. And it becomes even worse when you deep dive into the details and learn things like, that WinUI 2 and WinUI 3 are completely different, unrelated things. We all know Microsoft is bad at naming things, but sometimes it seems they're deliberately trying to reach new heights (or should I say lows) every now and then.

image-1.png

To me, that frustrating feeling of lacking continuity and reliability remains to this very day on many occasions. For example, just a few days ago, we learned about the all new Windows 11, and many in their excitement seem to have forgotten that not long ago we were told by the same Microsoft that Windows 10 is the last version of Windows. But the problem really isn't Windows 11. I'm actually looking forward to what it really brings us in terms of innovation. No, it just becomes harder and harder for me to watch these overly superlative, emotially faked presentations, where every sentence emphasizes how awesome and superior and amazing and incredible and stunning everything is. I secretly assume that anything I see will potentially be obsolete by the end of the Summer, or maybe next year.

Side note: Ironically, like many others I had to watch the Windows Event on Twitter, because Microsoft wasn't able to provide a working stream on their "superior" own infrastructure. Not the best promotion for the almighty Azure I guess.

I'm not alone with these thoughts. I've talked to some friends about the Windows event and we all agreed that a) there's way too much heroically delivered speech in these events for non-Americans not to cringe, and b) that it's wise to just wait a year and see what of this actually did become reality, and what has already been silently canceled or superseded then. Do you remember how Hololens changed the world and now all industry workers cannot imagine how they accomplished anything ten years ago, when they didn't have augmented reality? And how IoT did not become the most dangerous torrent of security flaws in history, but actually transformed our lifes dramatically, forever? Are you as impressed as I am by that super-developed AI we know as Cortana that never gets most-clumsily in your way in the worst moments? Did you, dear reader, also throw away your Chrome book when Windows 10X took the market by storm? Yeah, didn't think so. All of these have their niche, and some are amazing technologies. It's just that every year we see another hype that's so dramatically over-exaggerated that I basically pick what I'm going to really learn about next by re-watching shows from three years ago to see what's still relevant today.

grains-of-salt.jpg

The average amount of grains of salt I typically take with new Microsoft tech

Anyway.

There's also hope. For example, in the cloud space Microsoft has done an amazing job with many of their products in Microsoft 365. Yes, I admit they make the exact same mistakes I just mentioned there too: rebrand things every microsecond, move your cheese whenever you least expect it, and make understanding licensing as hard as possible. But their overall technological package is just superior in many ways.

For developers, TypeScript - in my opinion - is the most impressive technical innovation of the last decade. I'm happy to see it thrive, because it's simply fun to work with, it makes your life easier and more productive, but at the same time doesn't get in your way. Let's also briefly mention Visual Studio Code. I'm not quite ready yet to completely give up some of the text tools I've been using for the past 10 or 15 years, but nothing ever got as close as VS Code to get me to that point; I really only rarely use other editors anymore. And then of course there's .NET Core. Despite all the quirks and hiccups in its history I just mentioned, it was like a cleansing thunderstorm that put new life into .NET and left old burden behind. Open-source Microsoft sure seems on the right track with its development technologies.

And Blazor?

When I said I am a Microsoft sceptic, Blazor is a great example to describe what I mean. When a little more than two years ago one of my teams came to me and asked if they could try Blazor for a new project, I did what I had never done before: I said no. After all the back and forth with early .NET Core and .NET Standard, I simply wasn't ready to bet on another emergent Microsoft technology for an enterprise-grade project again. But this doesn't mean I'm not interested. Just like I said: I'm now used to letting a few years pass and see where it goes. I actually followed the technical development around Blazor closely, today more than ever. Two years later, I still have a strong opinion on that young technology, but quite noticable split into separate views on the different hosting models. So let's first talk about Blazor WebAssembly.

image-2.png

The schematic architecture of Blazor WebAssembly

Frankly, even today I would not consider one second to use Blazor WebAssembly for a production project. There's a reason that technology fell behind in maturity compared to Blazor Server and reached a rather trimmed-down general availability later than it. The sole benefit of Blazor WebAssembly, a full stack C# environment, falls short of coming anywhere near to outweigh its drawbacks compared to other, traditional JS-based frameworks. You still have to design and implement traditional APIs (Backend-For-Frontend), and master the deployments of multi-part applications, just like with any other other SPA. But now you have quite some additional challenges and unknowns ahead of you: dealing with JS-interop, debug and tooling limitations, and a rather shaky integration with CSS preprocessors or TypeScript transpilation. And then there's the issue with performance and application size. Performance of interpreted Blazor WebAssembly is low, which is one of the reasons why we're going to see an ahead-of-time (AOT) compilation feature in .NET 6. The thing is: compiled code becomes much larger, so you pay for performance with an even more increased application size, which is the reason not the whole app will be compiled. A mixed-mode AOT will focus on optimization of hot paths and important parts of the code. But even with AOT, we see something like JavaScript being 15x faster, and native C# sometimes up to 30x faster than Blazor WebAssembly C# (by the time of writing, using .NET 6 Preview 4). People trying to port something like Winforms Apps to Blazor WebAssembly experience things like a 20-fold decrease in performance.

Yes, some of these issues will get better and are already being worked on today, for example we're going to see improved tooling like hot reload in .NET 6. But why trade your existing, proved tool chain for that little gain of having C# in the browser today? It's just like I said: give it another two or three years, and either improved WebAssembly, increased bandwidth and superior tooling will have turned it into an amazing platform, or it's going to be the next Silverlight - time will tell.

But just because I have a somewhat well-tried JavaScript environment and experience doesn't really mean that I think all is good in that ecosystem. Quite the contrary.

node-modules-black-hole-small.jpg

Warning - it's not the pit of success

Even after years of experience we still struggle with seemingly simple things like, for example, reproducible builds. Check out some code you haven't touched in a year and even with a strict fixing of dependency versions you might simply fall on your face because someone pulled a package from a registry, and the proxy you set up exactly for this case decided to kick out that package due to an unlucky retention policy configuration. Everything always just feels like having too many moving parts that need to perfectly work together, or else.

Or take semantic versioning. It's a really great concept, as long as you don't expect it to work in practice. To put it with the words of XKCD: "Every change breaks someone's workflow". We had situations where a minor release fixing a bug upstream caused major issues simply because we had a workaround for that bug in place that then went crazy. Updating a .NET application, even with many NuGet dependencies, typically is a walk in the park compared to what we face on the client side. Even something like the update from .NET Core 3 to .NET 5 is ridiculously easy compared to, for example, updating Vue 2 to 3. And Vue is still on the friendly side, providing guides and (hopefully some time in the future) a migration build. We've had client libraries that used major updates to brutally throw breaking changes at you which were nothing less than a reimplementation of their whole public API. So yes, if there's a realistic chance to replace our today's SPA tool chain with something equally good in the .NET space, that is something to seriously consider. Which brings me to Blazor Server.

image-3.png

The architecture of Blazor Server

My opinion on Blazor Server is quite different to that on Blazor WebAssembly. When I first read about the concept, I was intrigued. Could this be possible? Feasible even? I had my doubts, but I also had some very positive experience with SignalR, the technical foundation used by Blazor Server. Again I took my time to actually try it out myself. But I'm glad I finally did. It's just amazing how well this works and what effort has been put into making these continuously exchanged messages between client and server as tiny as possible. I couldn't believe it works so well and that robust. The actual design concepts and decisions are equally great. If you know existing SPA frameworks, you'll find yourself at home in no time, because luckily most details work quite similar to real-world proven concepts instead of trying to reinvent the wheel. To be fair, that last point is not unique to Blazor Server but inherently to the component model and independent from the renderer you use.

A look back. When I was younger, in a time before we had the internet, "going viral" worked by publishing a book and waiting a few years until the ideas had spread around the globe. One of these ideas was "Rapid Application Development", by that time a fascinating new paradigm that I learned about from a book long lost during one of my relocations. When I learned about Blazor Server, at some point I thought: "Hey, in the 90s that would have been a best-in-class RAD tool". It's simply so flexible and easy to use that you can prototype an app extremely quickly. I also jokingly compare Blazor Server to WebForms all the time, because much of the event-driven model of Blazor Server reminds me of it, and also because I'm, well, just mean. But in all seriousness, Blazor Server in some way actually is a spiritual successor to WebForms for me, without most of the original drawbacks, all built upon modern tech. For example, due to SignalR, Blazor Server behaves like a "real" SPA even though you hook event handlers that execute in C# on the server side, just like 20 years ago. You have state handling for every client, but it doesn't use some heavyweight, obscure "view state" magic with client round-trips for that. An once again all emphasize is on "reusable components". It just feels like 2002 again. Like I said: everything old is new again.

Edit: I just learned that Jeff Fritz actually has created an (unofficial) proof of concept of a conversion tool from WebForms to Blazor 😲.

Compared with classic SPA frameworks, you have much more benefits than "just C#" with Blazor Server. Loading and starting up a Blazor Server app is lightweight and fast. You can eliminate your potentially costly API design and implementation of RESTful endpoints completely as long as you don't want to build a general-purpose API. Inject your dependencies straight into the view and directly access your backend services, or your business layer (or worse). And you don't have to worry about deploying a separate SPA somewhere, and master versioning or handling breaking changes between SPA/API releases. You can even get rid completely of the separate client-side build process, the corresponding CI pipeline, and probably also remove the client-side dependency management. The latter might not be completely true if you want to use CSS preprocessors or similar tooling though (more on that in a later post).

Of course there's also drawbacks to consider and new or unknown things to master. For example, in the many years of MVC and WebApi we've learned all about how to deal with stateless, http-based apps. And now with Blazor Server, you have to re-learn some of this, forget about HttpContext (danger zone!) and manage state on the server side properly. But that learning curve is easy, simply because the overall component model is quite elegant and most of the ideas are no different from other things you already have done a hundred times in your backend implementations. What I also like is that with that tech it's often harder to shoot yourself in the foot than to do the right thing, which always is a reliable sign you're working with something great.

So, would I consider using Blazor Server for production projects today?

Maybe. Sometimes when I read or hear what others are asking about Blazor, I start frowning. For example, when you struggle with SEO problems then to me that's an indicator you might want to use Blazor for something it's not primarily intended for. Would I build a publicly facing web site with Blazor? Very likely the answer is no. Would I use it for an internal low-volume or non-critical line of business app that benefits from quick results and a short "time to market"? Absolutely, yes. Somewhere in between there's a large gray zone of uncertainty. Blazor Server puts significantly more load on the, well, server. So you have to ask yourself: how many users am I going to serve? Is what I want to build a complex app with dozens of chit-chatty tiny events going back and forth all the time? Do I need to provide massive amounts of server-side state to my users so my app can work as expected? What about latency? Do I need to serve customers who sit half way around the globe? People with potentially shaky network connections? If some of these questions made you think twice, then there's a chance Blazor Server is not the best solution for your problem.

And finally, there's the question of trust. Do I trust Blazor Server with an operation-critical app? Do I trust Microsoft that they won't drop the ball (again)? Can I build critical business processes of a global company on top of that foundation? I'm still reluctant, but I'm tempted to say "yes".

Perhaps Microsoft is going to save the enterprise developer after all.

Tags: Blazor · Microsoft