Home .NET Blazor: Technical Introduction

Blazor: Technical Introduction

by admin

Today ASP.NET team announced that the Blazor project has been moved to the ASP.NET organization repository We’re starting the experimental phase to see if we can develop Blazor into a supported product. This is a big step forward!
Blazor: Technical Introduction
What is Blazor? It is a browser application framework written in .NET and run with WebAssembly. It gives you all the benefits of rich modern single-page applications (SPAs), while allowing you to use .NET from start to finish, all the way down to shared code on the server and client. In announcement post. details the major use cases, deadlines, and so on.
In this post I want to go deeper into the technical details for those who are wondering how it works.

Running .NET in a browser

The first step for building a .NET SPA framework is to somehow get the ability to run .NET code in a browser. Finally, this can be done using open standards and run in any browser (without any plugins), thanks to WebAssembly.
Currently WebAssembly is supported by all major browsers, including mobile ones. It is a compact bytecode format, optimized to reduce the amount of downloaded data and speed up execution. Despite what many developers might think, WebAssembly is not introduces no new security problems, because they are not normal binary files (like x86/x64) – they are a new format containing bytecode that can only do the same thing as JavaScript.
So how does it allow us to run .NET? All thanks to the fact that Mono team added WebAssembly support to their project In case you missed the news, the Mono project became part of Microsoft in 2016. Mono is an official .NET rant for client platforms (such as native mobile apps and games). WebAssembly is just another client platform, so it makes sense that Mono should work on it.
Mono can run on WebAssembly in two modes : interpretation mode and AOT.

Interpretation

In interpretation mode Mono randomizer compiles to WebAssembly, but your .NET assemblies do not. The browser loads and runs the rantime, which in turn can load and run standard .NET assemblies (normal .NET .dll files) built by a normal .NET tulchan.
Blazor: Technical Introduction
This is similar to how, for a regular CLR, the core kernel is distributed compiled into native code, which then loads and executes .NET builds. The only key difference is that the desktop CLR actively uses JIT compilation to speed up execution, while Mono on WebAssembly works closer to the classical interpretation model.

Ahead-of-time (AOT) compilation

In AOT mode, your .NET application becomes a pure WebAssembly binary immediately at build time. There is no interpretation in runtime – your code runs as normal WebAssembly code. This mode still requires some of the Mono runtime (low-level .NET services such as garbage collection) to be loaded, but allows you to discard components such as the .NET file parser.
Blazor: Technical Introduction
It’s similar to how since time immemorial ngen utility allows AOT compilation of .NET assemblies to native machine code, or to the recent full native AOT .NET runtime. CoreRT

Interpretation mode vs. AOT

Which mode is better? We don’t know yet.
However, we know that Interpreter mode gives a much faster development process than AOT. After modifying the code, you can rebuild it with the normal .NET compiler and get the updated application in the browser in seconds. AOT compilation, on the other hand, can take minutes.
The obvious thought is that interpretation mode will be primary for development, and AOT for production.
But all of that may not be true at all, because the interpretation mode is surprisingly much faster than you might think. And we’ve heard from the folks at Xamarin who use .NET for native mobile apps that regular (non-AOT) .NET builds are very small and lend themselves well to compression, unlike AOT builds. We’ll look at both until we have a chance to objectively evaluate the difference.

Blazor, SPA framework

Being able to run .NET in a browser is a good start, but it’s not enough. To be a productive application developer, you need a consistent set of standard solutions for standard problems-such as UI creation/reuse, state management, routing, unit testing, build optimization, and so on. All of this should be designed around the strengths of .NET and the C# language, allowing you to get the most out of the existing .NET ecosystem and come with top-notch tool support as the .NET developer expects.
Blazor is all of the above. It is inspired by today’s best SPA frameworks like React, Vue and Angular, as well as some UI stacks from Microsoft like Razor Pages. Our goal is to give web developers something that fits as well as possible with .NET.

Components

In all modern SPA frameworks, applications are built from components. A component is usually some kind of UI element: a page, a dialog box, a set of tabs, or a form. Components can be nested, reused, and shared between projects.
In Blazor, a component is a .NET class that you can write directly (that is, as a C# class) or, more commonly, as a Razor markup page (.cshtml file).
Appeared approx. in 2010 Razor is a syntax for combining markup with C# code. It is designed specifically for developer productivity, allowing you to switch between markup and C# without any ado, with full support for intellisense The example below shows a simple dialog component described in the Razor file MyDialog.cshtml:

<div class="my-styles"><h2> @Title</h2>@RenderContent(Body)<button onclick=@OnOK> OK</button></div>@functions {public string Title { get; set; }public Content Body { get; set; }public Action OnOK { get; set; }}

When you use this component, the toolkit knows what to tell you :
Blazor: Technical Introduction
Many design patterns can be built on this simple foundation, including popular patterns from SPA frameworks like stateful components, stateless components, and higher-order components. You can nest components within each other, generate them procedurally, share them between libraries, run unit tests without the need for a browser, and generally live the good life.

Infrastructure

When creating a new project, Blazor will offer the basic services most applications need :

  • Templates
  • Routing
  • Dependencies implementation
  • Lazy loading (that is, loading parts of an application as needed)
  • Unit testing

An important aspect of the architecture is that all of this is optional. If you don’t use something, it will be removed from the final build when published.
Another important point is that only a few of the lowest-level parts are in the core of the framework. For example, the routing and template system are not like that – they are implemented in a "user-space", meaning that this code can be written by the application developer without using any internal APIs. So if you don’t like our routing or template system, you can replace them with your own. Our current prototype template system is about 30 lines of C# code, so you can easily figure it out and rewrite it if you want.

Deployment

Obviously, a large part of Blazor’s target audience is ASP.NET developers. For them, we will release middleware to transparently host the UI on Blazor with additional features like pre-rendering on the server.
Equally important to us are developers who don’t use .NET at all yet. To make Blazor viable for developers who prefer Node.js, Rails, PHP or any other server-side technology, or who write serverless applications, we absolutely will not require .NET on the server. The result of building a Blazor application is the dist folder, which contains only static files. We can distribute them from the Github pages, from cloud storages, through Node.js servers, or just about anything.

Common code and netstandard

NET standard is a way to describe the level of features provided by the .NET runtime or required by the .NET build. If your .NET early stage supports netstandard2.0 and below, and you have an assembly targeting netstandard2.0 and above, you will be able to run this build on this runtime.
Mono on WebAssembly will support netstandard2.0 or higher version (depending on the release date). This means that you will be able to use your .NET libraries in both backend and browser applications. For example, you might have a project with business logic model classes – you can use it on both the server and the client. And, of course, you can download packages from NuGet.
However, not all .NET APIs make sense in a browser. For example, you can’t listen to an arbitrary TCP socket, so System.Net.Sockets.TcpListener won’t do anything useful. Also, you almost certainly should not use System.Data.SqlClient in a browser application. And that’s not a problem, because, first, browsers do support APIs that people actually need to create web applications, and second, the .NET standard has a handling mechanism for such cases. The base class system (BCL) will throw a PlatformNotSupported exception when calling platform-specific APIs that are not applicable. This may cause problems in the beginning, but over time the authors of NuGet packages will modify their libraries to support different platforms. If .NET wants to move towards The world’s fastest-growing application platform – is a stepping stone that will have to be climbed.

JavaScript/TypeScript compatibility

Even if you write a C#/F# browser-based application, sometimes you need to plug in someone else’s JavaScript library or your own JavaScript/TypeScript code to call some new browser-based API.
This should be very easy, because the WebAssembly standard is designed to interact with JavaScript (which is no surprise) and we can easily use this in .NET code.
To work with other people’s JavaScript libraries, we explore the possibility of using TypeScript type definitions in C# code with full intellisense. This will make about 1000 of the most popular JS libraries very easy to integrate.
The current approach for calling other libraries or your JS/TS code from .NET is to register a named function in the JS/TS file. For example :

// This is JavaScriptBlazor.registerFunction('doPrompt', message => {return prompt(message);});

and then create a wrapper to be called from .NET:

// This is C#public static bool DoPrompt(string message){return RegisteredFunction.Invoke<bool> ("doPrompt", message);}

Approach with registerFunction has the nice bonus of working well with JavaScript builders like Webpack.
And, to save you time and nerves, the Mono team is working on a library that will worm the standard browser APIs into .NET.

Optimization

Historically, .NET has focused on platforms where application size is not such a big deal. It doesn’t make much difference whether your ASP.NET application weighs 1MB or 50MB. It’s a medium problem for desktop or mobile applications. But for browsers, the download size is very critical.
In defense, the .NET on WebAssembly will most likely be loaded only once. You can use standard HTTP caching (or even fancy stuff like service worker) to ensure that the user will only load the kernel once. And with CDN, the user can have one download at a time to several applications.
That’s all well and good, but I don’t think it’s enough. If the rant weighs 20MB, it’s still too much, even for a one-time download. It’s not a browser plugin after all-it’s a normal, standards-based web application. Even the very first download should be fast.
So we put a lot of effort into reducing the size of the load. We see the following 3 phases of optimizations :

1. Reducing the Mono rant

The Mono runtime contains a lot of desktop-specific features. We hope that Blazor will contain a stripped down version of Mono, which is significantly smaller than the full distribution. In a manual optimization attempt, I was able to remove about 70% of the wasm rantime file without disrupting the underlying application.

2. Reducing IL code when publishing

Linker .NET IL (based on Mono linker ) performs static analysis, determining which parts of the .NET libraries can be called from your application, and removes everything else.
This is similar to the tree shaking in JavaScript , the difference is that the IL shaking is much more precise and works at the individual method level. This removes all unused system library code, which makes a huge difference in most cases, often reducing the size of the application by another 70+%.

3. Compression

Finally, and most obvious, we expect your server to support HTTP compression. This usually cuts off another 75% of the volume.
Of course, a .NET web app will never be as tiny as the simplest React app. Our goal is to make it so small that the average user on an average connection won’t even notice the very first download, let alone subsequent cache downloads.

So what’s all this for?

Whether you like it or not, web development is going to change dramatically in the next few years. WebAssembly will allow web developers to choose from a much larger list of languages and platforms than ever before. And that’s a good thing – our world is finally maturing. Server software and native application developers have always been able to choose the language and paradigms that best fit their problems, fit the culture of the team, and are backed by existing knowledge. Dreaming of writing functionality in Haskell or Lisp for your financial application? Want some low-level C? Are you an Apple developer and want to continue using your Swift knowledge? It’s all coming to the web.
Don’t be intimidated. It doesn’t mean that you will have to know all these languages. It means that we will all become ordinary software developers. Your current knowledge of browser programming is still relevant and valuable, but you will have new ways to express your ideas and more points of contact with other developer communities.
And our initiative is to put .NET at the forefront of this movement, rather than dragging behind, years behind.

Current status

Feeling the urge to give it a try? Slow down – we’re still in the very early stages of the project. Nothing is ready to download yet and much of the above is in progress. Most of you should just relax and wait, the first pre-alpha builds will be available in about a month.
Remember, Blazor is currently an experiment for the ASP.NET team. It will take us a few months to see if we can turn it into a full fledged, supported product. We’re not promising anything yet, so don’t build your business plans around Blazor!
And if you’re really interested, check out the repository , try to build it, run the tests, and come talk to us You can even look up // TODO comments and submit a Pull Request, or share an idea for a cool fic.


From the translator

I will conclude with some interesting links :

You may also like