diff --git a/misc/blazor-frustrations/assets/blazor_css_isolation1.png b/misc/blazor-frustrations/assets/blazor_css_isolation1.png new file mode 100644 index 0000000..02ad682 Binary files /dev/null and b/misc/blazor-frustrations/assets/blazor_css_isolation1.png differ diff --git a/misc/blazor-frustrations/assets/blazor_css_isolation2.png b/misc/blazor-frustrations/assets/blazor_css_isolation2.png new file mode 100644 index 0000000..6080b21 Binary files /dev/null and b/misc/blazor-frustrations/assets/blazor_css_isolation2.png differ diff --git a/misc/blazor-frustrations/assets/blazor_css_isolation3.png b/misc/blazor-frustrations/assets/blazor_css_isolation3.png new file mode 100644 index 0000000..05c6ddc Binary files /dev/null and b/misc/blazor-frustrations/assets/blazor_css_isolation3.png differ diff --git a/misc/blazor-frustrations/assets/blazor_css_isolation4.png b/misc/blazor-frustrations/assets/blazor_css_isolation4.png new file mode 100644 index 0000000..6849b9b Binary files /dev/null and b/misc/blazor-frustrations/assets/blazor_css_isolation4.png differ diff --git a/misc/blazor-frustrations/assets/blazor_css_isolation5.png b/misc/blazor-frustrations/assets/blazor_css_isolation5.png new file mode 100644 index 0000000..6374a94 Binary files /dev/null and b/misc/blazor-frustrations/assets/blazor_css_isolation5.png differ diff --git a/misc/blazor-frustrations/meta.yml b/misc/blazor-frustrations/meta.yml new file mode 100644 index 0000000..cf5f941 --- /dev/null +++ b/misc/blazor-frustrations/meta.yml @@ -0,0 +1,13 @@ +Created: 2024-07-15 12:20:00 +Updated: 2024-07-15 12:20:00 +Title: Blazor Gotchas I Am Frustrated By +Slug: blazor-gotchas-i-am-frustrated-by +Description: Blazor is a wonderful looking technology but unfortunately it has some pain points. +Tags: + - rants + - blazor + - c# + - dotnet + - programming + - software + - web \ No newline at end of file diff --git a/misc/blazor-frustrations/post.md b/misc/blazor-frustrations/post.md new file mode 100644 index 0000000..0882cf4 --- /dev/null +++ b/misc/blazor-frustrations/post.md @@ -0,0 +1,153 @@ +## Intro +For as long as browsers have existed, there has been one and only one programming language that has dominated developing the web: JavaScript. And as long as there has been JavaScript, there's been bemoaning and complaints about the inadequacies and inconsistencies of the language. Some of it is warranted. Some of it is not. Regardless, many an individual, companies and the like have attempted to replace JavaScript with something else. Something better. + +Blazor is Microsofts latest (more on that in a moment) attempt to leverage their existing Dotnet ecosystem to do just that: make JavaScript obsolete and write web applications and websites with C# and Dotnet. + +## Brief History Of JavaScript Replacements +Replacement attempts to JavaScript are not a new concept. It has been attempted probably almost as soon as the language gained prominence in the mid to late 90s. The late 90s and early 00s saw the rise and fall of Java applets: tiny applications written in Java that could be embedded into a website as a standalone component. The early 2000s introduced the world to Flash and due to the multimedia capabilities (none of which was present at the time in html, css or JavaScript) it became a very popular way of displaying animated and lively content. Actionscript, a close cousin to JavaScript, allowed even further power to developers. Most people probably remember games and video players from that era that popped up pretty much everywhere. Flash sizzled out as a technology in less than a decade mostly, I argue, due to html 5 and the release of Google Chrome and it's V8 engine. + +In the same time frame Flash was getting notoriety, Microsoft released its first attempt at a solution in the form of Silverlight. Silverlight was essentially the same concept Blazor leverages today: Write your code in C# and xaml without any need to write JavaScript. However, due to poor adoption by browsers and emergence of html 5 put a cap in that technology quickly. + +Microsoft's second attempt came through ActiveX but unlike Silverlight, ActiveX allowed a broader range of programming languages. Security issues and decline in Internet Explorer (the only browser truly supporting the technology) popularity proved the downfall of this attempt as well. + +Others too, tried and failed. Some attempted to replace JavaScript entirely with different languages. Others opted for a halfway solution via extensions to JavaScript itself like CoffeeScript and more recently TypeScript. JavaScript development itself transformed as well to a point that few these days write it raw, opting to use frameworks such as React or Angular. Then came Blazor. + +## About Blazor +Somewhere in 2010s, the existing .NET was deemed unsuitable for future development. Or so I assume. Regardless, a new framework arose alongside it called .NET Core. By the time version 3.1 had come out, a decision was made to merge the two into a single unified .NET, which later would be released as .NET 5, skipping version 4 entirely (Microsoft likes to skip numbers). + +During the Core era in 2017, Blazor arose as an experiment in Oslo by Steve Sanderson. It didn't take long for Blazor to receive an official slot in the .NET ecosystem and by the time .NET 5 came out it was all but an official piece of the .NET pie. Ironically, that was also the era when Blazor stopped working on Internet Explorer and older versions of Microsoft Edge, which, looking back at the history of these attempts, is almost a scandalous prospect to contemplate. + +Blazor leverages a new browser technology known as WebAssembly that, in short, attempts to allow a new interface to develop software in the web that runs in the browser. It is not a drop-in replacement for JavaScript but seems like it was designed to allow offloading some heavier calculations to a faster engine and code than what the browser engine currently allows. JavaScript is fast. Blazing fast since the inception of the Chrome V8 engine (and further developments since) then but the age of the engines and the language is starting to show. Yet, the web being the universal interface and backward compatibility is a hard requirement, rewriting everything from scratch and deprecating decades of history would be a suicide as far as technology adoption is concerned. Hence, WebAssembly. + +What blazor does, from simply the developer's perspective, is it allows you to write your code in Razor and C# and the code is then compiled into WebAssembly. You are, in essence, running an entire .NET framework in your browser. An interop JavaScript exists to translate .NET code into JavaScript and vice versa. WebAssembly does not have access to DOM, the primary means with which to affect the web page and thus, this "glue" is required to make anything possible. + +Blazor comes in two flavors: server side (known as blazor server or simply blazor) and client side (blazorwasm). The difference between the two is as follows. + +Blazor server runs on the server (duh). Each interaction with the page from the user is sent to the server. That means your clicks, selects, text inputs etc. need a roundtrip to the server before being processed and response displayed on the page. Websocket, which is a browser's real-time two-way communication platform, serves as the go-between of these interactions so the experience is still app like. + +Blazorwasm on the other hand, acts more like Angular or React that the code managing the web page all live in the browser. + +And with this difference, we come to my first annoyance with the technology. + +## The Subtle Differences Between Wasm And Server Can Bite You In The Ass +Blazor comes off as a singular unified concept and it actually pulls it off as far as developer experience goes. Mostly. There are however differences that will infuriate you if you don't know it beforehand. Here's what I stumbled on. + +My experience with Blazor began through wasm. I felt like running every click and type to the server would be an unacceptable delay and dependent way too much on an active and robust internet connection. However, as I began to write an app that was meant to run in the local machine alone (meaning served locally on the machine as well) I felt Server was worth looking into since any network delay would be negligible. Imagine then my shock when I leveraged my wasm knowledge and when it was time to click, nothing happened. No events were fired. No interactivity of any kind. The page showed content alright but when it was time to submit forms or handle click events, nada. + +My naivete in the uniformity of Blazor became my small undoing. In retrospect, I suppose I should have treated Blazor Server and Blazor Wasm something like AngularJS and Angular but hey they *seem* to work the same in every other respect. + +You see, as it turns out, Blazor **Server** has a unique trait called **Render Mode**. What is Render Mode? Well, as I see it, it instructs Blazor to optimize itself. If you only present information and have no interactivity, you really don't need all that boilerplate and plumbing to handle all those clicks that never materialize. Hence, Blazor acts like a static website instead. Plain content. Render Mode needs to be in `InteractiveServer` mode for that to work. + +And it is **not** ON by default. + +I know. I know. RTFM, right? Cut me some slack, please. If everything else works almost as universally between the two variants, is it reasonable to even assume this kind of little tidbit to be necessary for one to work and not the other? I say no. + +It confuses me as to the justification for a setting like Render Mode and why is it how it is by default. One would imagine the primary purpose of Blazor to be the desire to create a single-page application experience and real time app. Why would you then disable by default all the code necessary to make that interactivity happen? I do not understand. After all, if you want to create just a static page, create a bloody static site. We have the technology. Personally, I'd have gone the opposite route: enable interactivity by default and for those who wanted to finetune case-by-case basis, allow this mode to be tweaked. + +And by the way, there is no indication of any kind that this mode is the culprit. No log messages or error messages or warnings that interactive mode is X. I went down the rabbit hole trying to unravel why my components were disposed immediately after init thinking there was a bug in the framework itself before realizing this snafu. + +Anyway, now I know you need this mode. And now, so do you. I hope this saves you a couple of hours of frustration, debugging and grey hairs. The good thing is, you only need to do it once in `App.razor` and the effect trickle's down like a booming capitalist economy. Unless you really want to do that fine-tuning per page or something. + +This is what it takes by default to make all your pages and components interactive: + +```html +
+