Web assembly and the future of the web

Introducing Web assembly with Blazor

What is web assembly?

Web assembly is pre-compiled code which can run in the browser. Since it is pre-compiled, web assembly can also be compiled from an impressive amount of languages including:

Using the respective frameworks, code is compiled into binary format .wasm files. The appeal of Web assembly comes from two main points:

  • Raw speed — web assembly is in most cases faster than the conventional JavaScript(more on this in a bit)
  • Security by obfuscation — .wasm files only contain processor instructions and because of this it is very hard to view/modify the original source code. Head over to the live blazor demo and have a look at the source files

What is browser support like for web assembly?

As of April 2020, 90% of browsers used today are supported (source: caniuse.com ). The notable outliers are IE, opera mini and UC browser.

Browser Support — usage relative graph from caniuse.com

Architectural differences

WebAssembly is structurally different from JavaScript the ground up, however, it still maintains all of Javascript’s functionality. This is because the WebAssembly JavaScript API wraps exported WebAssembly code with JavaScript functions that can be called normally, and WebAssembly can import and synchronously call normal Javascript functions. WebAssembly also shares the same module structure as ES2015 modules.

With all of the above kept in mind, WebAssembly still depends on JavaScript— with the current implementation, JavaScript maintains full control on how WebAssembly is downloaded, compiled and run. WebAssembly is not trying to replace JavaScript, rather it is looking towards accelerating high-performance functions.

WebAssembly compilation process — from mozilla documentation

WebAssembly also cannot access the DOM directly. To change the DOM it needs to make a call out to Javascript, which then calls the Web APIs on WebAssembly’s behalf. Emscripten creates the HTML and JavaScript glue code needed to achieve this when using C++. Emscripten not only handles these calls, but it also implements popular libraries like SDL, OpenGL, OpenAL and parts of POSIX.

To add to this, blazor compiles code to .dll files before converting them to web assembly, so when we use something like blazor, the full process would look like this:

This is in stark contrast to how it is done in V8:

“When V8 compiles JavaScript code, the parser generates an abstract syntax tree. A syntax tree is a tree representation of the syntactic structure of the JavaScript code. Ignition, the interpreter, generates bytecode from this syntax tree. TurboFan, the optimizing compiler, eventually takes the bytecode and generates optimized machine code from it.”

Let’s talk performance

The following contains a list of benchmark links you can use to test performance of web assembly on your machine:

3D animated figures

Algorithm testing

WebAssembly Video Editor

PSPDFKit’s blog (they view, annotate, and fill out forms in PDF documents)

On our machine, the fibonacci test was 1.78x faster using webassembly when compared to pure JavaScript.

The Competition

The following is a list of the frameworks available to write web assembly:

In our opinion, the least experimental is blazor. This was also chosen due to our previous experience with C#/Java and our need for strong typing.

A hello world example in Blazor

Before we jump into coding..let’s set up our environment.

You’ll need to install Microsoft Visual studio, with the >ASP.NET and web development workload. If you’d like to have debugging ensure you have installed the latest preview release of Visual Studio 2019 16.6 (Preview 2 or later).

You’ll also need to install the web assembly commands tool using the following command in your terminal:

dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview4.20210.8

Now that the installation is complete, create a new project by doing the following:

  • Select new project

  • Select Blazor app

  • Fill in the project details and select create

  • Select “blazor web assembly app” and be sure to check the Progressive Web Application option (more on this in a bit)

After creating your app, you can run it using CTRL+F5

If all is working well, a new browser window should open up with the default Hello World template:

What makes this all tick?

Let’s head over to pages — counter.razor that was created in the default template. The contents of the file are as follows:

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
private int currentCount = 0;

private void IncrementCount()
  {
    currentCount++;
  }
}

When the user clicks the increment button, the following things happen:

  1. The onclick event is fired
  2. The IncrementCount is called
  3. currentCount is incremented
  4. The razor component is rerendered

It is also important to note the route definition on the first line.

What’s PWA and how do I add it?

A PWA app is an app which is installable as a “system app” on a host system. This allows it to cache resources using the service worker, and possibly run offline. For a brief intro to PWAs, refer to our previous blog post .

In the initial setup, we specified that the app should be a PWA in the hello world project setup. This option creates a new installation option in the browser to install the app:

Installation of PWA (from microsoft’s documentation )

Compared to the Angular/React, the initial setup in making your app a PWA is significantly easier, however, the usual caveats with PWAs still apply. These include limited browser support, and offline functionality needs to be implemented manually (which may require significant changes to your current project architecture). An example of this might be a live text editor — your app needs to manually implement a syncing method to communicate with your backend once the user comes back online. There is also no support for debugging service workers as of writing this article in visual studio 16.6.0 Preview 3.0.

Downsides when using blazor

The main downside with Blazor is that it does not support hot reloading. This means that when you apply your changes, you need to do a full rebuild of your project every time. The devs working on blazor had this to say on the topic :

This is planned for .NET 5, which is scheduled for Nov 2020. We’re still having lots of discussions on what approach we want to take here.

There are solutions to this such as LiveSharp and using dotnet watch however, livesharp is not an official solution and the watch command still needs a manual browser refresh when a change is detected. Other optimisations to reducing build time involve removing circular dependency detection, which feels like a bad idea in our eyes.

When compared to frameworks like angular and react, this means that development time can be significantly slower.

Debugging

To debug blazor apps, you need to ensure you have installed the latest preview release of Visual Studio 2019 16.6 (Preview 2 or later). Once you have it set up, you can use breakpoints within visual studio to debug your code. As of right now, this is what you can and can’t do with the visual studio debugger (taken from their documentation)

Available scenarios include:

  • Set and remove breakpoints.
  • Run the app with debugging support in Visual Studio and Visual Studio Code (F5 support).
  • Single-step (F10) through the code.
  • Resume code execution with F8 in a browser or F5 in Visual Studio or Visual Studio Code.
  • In the Locals display, observe the values of local variables.
  • See the call stack, including call chains that go from JavaScript into .NET and from .NET to JavaScript.

For now, you can’t:

  • Inspect arrays.
  • Hover to inspect members.
  • Step debug into or out of managed code.
  • Have full support for inspecting value types.
  • Break on unhandled exceptions.
  • Hit breakpoints during app startup.
  • Debug an app with a service worker.

Cool demos

This repository contains a curation of creations that show the potential web assembly: https://github.com/mbasso/awesome-wasm#examples

One of our favourites is Cubes — a port of the bullet physics engine. Awesome blazor is another curation of demos and guides which is worth checking out.

Final thoughts

As of right now, web assembly and blazor feel like a solid proof of concept, with evidence to show their superior performance, but the lack of tools make it hard to justify using it in a production environment — mainly due to increased development costs in resolving issues and creating new features.

Tags

Security
Blazor
menu_icon
Gabriel Stellini

17th April 2020