Aug 27 2021

What’s new in Blazor WebAssembly 6

Category: Blazor | Blazor Controls ToolkitFrancesco @ 11:30

With the new .Net 6.0, tat is still in preview,  Blazor WebAssembly gained new interesting features, such as error boundaries, AOT compilation, query-string handling, and the dynamic component. Each of the upcoming new feature will be described in a separate section.

Error boundaries

As a default when an error in a component occurs, the exception is intercepted by the .Net runtime that automatically makes visible the error code contained in index.html:

<div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">??</a>
</div>

In the new version component exceptions can be intercepted by the new <ErrorBoundary> component, as shown in the example below:

@foreach (var forecast in forecasts)
{
    <ErrorBoundary>
        <ChildContent>
        <tr>
            <td>@forecast.Date.ToShortDateString()</td>
            <td>@forecast.TemperatureC</td>
            <td>@forecast.TemperatureF</td>
            <td>@forecast.Summary</td>
        </tr>
        </ChildContent>
        <ErrorContent>
        <tr>
            <td colspan="4" class="my-error">Nothing to see here. Sorry!</td>
                    
        </tr>
        </ErrorContent>

    </ErrorBoundary>
}

The <ChildContent> template contains the markup to check. Whenever, an exception is thrown by a component inside <ChildContent> the markup inside <ErrorContent> is shown and the exception is caught.

AOT Compilation

Once uploaded in the Browser, .Net assemblies are not compiled Just-In-Time (JIT) at their first execution as it is the case for other platforms. Instead, they are interpreted by a very fast interpreter. Just the .Net runtime is pre-compiled and uploaded in the Browser directly in WebAssembly.

JIT compilation is avoided since it would considerably increase the application start time, that already is quite high because of the high application download size (about 10Mb). In turn, the download size is high due to the .Net libraries that any Blazor application needs to work properly.

In order to reduce download size, during the compilation in release mode, Blazor .Net assemblies are tree-shaken to remove all unused types and methods. However, notwithstanding this tree-shaking, the typical download size remains quite high. A good download improvement is achieved with the default caching of the .Net runtime which reduces the download size to 2-4 Mb. However, the download size still remains high the first time a Blazor application is visited.

Staring from .Net 6, Blazor offers an alternative to JIT compilation: Ahead-Of-Time (AOT) compilation. With AOT all application assemblies are compiled into a unique WebAssembly file during the application publication. On the average AOT compilation makes the code 4 times faster (from 2 times to 10 times faster). Unluckily, AOT compilation increases more than twice the download size, since the compiled code is more verbose than the source .Net code. Therefore, AOT should be adopted only in performance-critique application that can trade a higher start time for a better performance.

AOT compilation is very slow and may last something like 10 minutes also in the case of small applications. On the other side, it must be executed only once when the application is published, so the compilation time doesn’t impact on the application start time.

.NET WebAssembly AOT compilation requires an additional build tool that must be installed as an optional .NET SDK workload in order to use. The first time you can install it with the shell command below:

dotnet workload install microsoft-net-sdk-blazorwebassembly-aot

Instead, when a new .Net version is installed, it is enough to launch the following command to update all previously installed workloads:

dotnet workload update

Once the AOT workload has been installed AOT compilation can be enabled on per-project basis by adding the <RunAOTCompilation>true</RunAOTCompilation> declaration to the Blazor project file, as shown below:

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

Page URLs Support Query Strings

In the new .Net 6 version pages can extracts parameters also from the URL query string. Thus, for instance, if a page with URL @page “OrderItem/{id}” is invoked with the OrderItem/3?quantity = 123 URL, then it can capture the quantity parameter. This parameter can be captured by a page property math matches “quantity” in a case-insensitive comparison, and that is decorated with the [SupplyParameterFromQuery] attribute, as shown below:

@code {
    [Parameter]
    [SupplyParameterFromQuery]
    public int Quantity { get; set; } = 0;

Dynamic Component

The new <DynamicComponent> makes easy to a variable content to a page. More specifically, <DynamicComponent> is passed the type and the parameters of a component and invokes it as shown below:

<DynamicComponent Type="@componentType" Parameters="@parameters" />

@code {
    private Type componentType = ...;
    private IDictionary<string, object> parameters = ...;
}

The component actually rendered by the dynamic component can be accessed trough its Instance property, and, when needed, refreshed as shown in the example below:

<DynamicComponent Type="@componentType" Parameters="@parameters" @ref="dc" />

@code {
    private DynamicComponent dc;
    

    private Type componentType = ...;
    private IDictionary<string, object> parameters = ...;
    ...
    private Task Refresh()
    {
        return (dc.Instance as IRefreshable)?.Refresh();
    }
    
}

 

Multi-Select Support

In version .Net 6 when a <InputSelect> component is bound to an IEnumerable<T> it is rendered as a multi-select, thus enabling the user to select multiple values.

 

That's all

 

Francesco Abbruzzese

Tags: ,