ASP.NET Core updates in .NET 6 Preview 3

Daniel

.NET 6 Preview 3 is now available and includes many great new improvements to ASP.NET Core.

Here’s what’s new in this preview release:

  • Smaller SignalR, Blazor Server, and MessagePack scripts
  • Enable Redis profiling sessions
  • HTTP/3 endpoint TLS configuration
  • Initial .NET Hot Reload support
  • Razor compiler no longer produces a separate Views assembly
  • Shadow-copying in IIS
  • Vcpkg port for SignalR C++ client
  • Reduced memory footprint for idle TLS connections
  • Remove slabs from the SlabMemoryPool
  • BlazorWebView controls for WPF & Windows Forms

Get started

To get started with ASP.NET Core in .NET 6 Preview 3, install the .NET 6 SDK.

If you’re on Windows using Visual Studio, we recommend installing the latest preview of Visual Studio 2019 16.10. If you’re on macOS, we recommend installing the latest preview of Visual Studio 2019 for Mac 8.10.

Upgrade an existing project

To upgrade an existing ASP.NET Core app from .NET 6 Preview 2 to .NET 6 Preview 3:

  • Update all Microsoft.AspNetCore.* package references to 6.0.0-preview.3.*.
  • Update all Microsoft.Extensions.* package references to 6.0.0-preview.3.*.
  • Update calls to TryRedeemPersistedState on ComponentApplicationState to call TryTakePersistedState instead.
  • Update calls to TryRedeemFromJson on ComponentApplicationState to call TryTakeAsJson instead.

See the full list of breaking changes in ASP.NET Core for .NET 6.

Smaller SignalR, Blazor Server, and MessagePack scripts

Thanks to a community contribution from Ben Adams the SignalR, MessagePack, and Blazor Server scripts are now significantly smaller, enabling smaller downloads, less JavaScript parsing and compiling by the browser, and faster start-up.

The download size reduction from this work is pretty phenomenal:

Library Before After % 🠓 .br
signalr.min.js 130 KB 39 KB 70% 10 KB
blazor.server.js 212 KB 116 KB 45% 28 KB

You also now only need the @microsoft/signalr-protocol-msgpack package for MessagePack; no need to include msgpack5. This means you only need an additional 29 KB rather than the earlier 140 KB to use MessagePack instead of JSON.

Here’s how this size reduction was achieved:

  • Updated TypeScript and dependencies to latest versions.
  • Switched from uglify-js to terser, which is webpack’s default and supports newer JavaScript language features (like class).
  • Marked the SignalR modules as "sideEffects": false so tree-shaking is more effective.
  • Dropped the "es6-promise/dist/es6-promise.auto.js" polyfill.
  • Changed TypeScript to output es2019 rather than es5 and dropped the “es2015.promise” and “es2015.iterable” polyfills.
  • Moved to msgpack5 from @msgpack/msgpack as it requires less polyfills and is TypeScript & module aware.

You can find more details on these changes in Ben’s pull request on GitHub.

Enable Redis profiling sessions

We accepted a community contribution from Gabriel Lucaci to enable Redis profiling session with Microsoft.Extensions.Caching.StackExchangeRedis in this preview. For more details on Redis profiling, see the official documentation. The API can be used as follows:

services.AddStackExchangeRedisCache(options =>
{
    options.ProfilingSession = () => new ProfilingSession();
})

HTTP/3 endpoint TLS configuration

Work is beginning to ramp up on support for HTTP/3 in .NET 6. HTTP/3 brings a number of advantages over existing HTTP protocols, including faster connection setup, and improved performance on low-quality networks.

New in this preview is the ability to configure TLS certificates on individual HTTP/3 ports with UseHttps. This brings Kestrel’s HTTP/3 endpoint configuration in-line with HTTP/1.1 and HTTP/2.

.ConfigureKestrel((context, options) =>
{
    options.EnableAltSvc = true;
    options.Listen(IPAddress.Any, 5001, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http3;
        listenOptions.UseHttps(httpsOptions =>
        {
            httpsOptions.ServerCertificate = LoadCertificate();
        });
    });
})

Initial .NET Hot Reload support

Early support for .NET Hot Reload is now available for ASP.NET Core & Blazor projects using dotnet watch. .NET Hot Reload applies code changes to your running app without restarting it and without losing app state.

To try out hot reload with an existing ASP.NET Core project based on .NET 6, add the "hotReloadProfile": "aspnetcore" property to your launch profile in launchSettings.json. For Blazor WebAssembly projects, use the "blazorwasm" hot reload profile.

Run the project using dotnet watch. The output should indicate that hot reload is enabled:

watch : Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload. Press "Ctrl + R" to restart.

If at any point you want to force the app to rebuild and restart, you can do so by entering Ctrl+R at the console.

You can now start making edits to your code. As you save code changes, applicable changes are automatically hot reloaded into the running app almost instantaneously. Any app state in the running app is preserved.

.NET Hot Reload

You can hot reload changes to your CSS files too without needing to refresh the browser:

CSS hot reload

Some code changes aren’t supported with .NET Hot Reload. You can find a list of supported code edits in the docs. With Blazor WebAssembly only method body replacement is currently supported. We’re working to expand the set of supported edits in .NET 6. When dotnet watch detects a change that cannot be applied using hot reload, it falls back to rebuilding and restarting the app.

This is just the beginning of hot reload support in .NET 6. Hot reload support for desktop and mobile apps will be available soon in an upcoming preview as well as integration of hot reload in Visual Studio.

Razor compiler no longer produces a separate Views assembly

The Razor compiler previously utilized a two-step compilation process that produced a separate Views assembly that contained the generated views and pages (.cshtml) defined in the application. The generated types were public and under the AspNetCore namespace.

We’ve now updated the Razor compiler to build the views and pages types into the main project assembly. These types are now generated by default as internal sealed in the AspNetCoreGeneratedDocument namespace. This change improves build performance, enables single file deployment, and enables these types to participate in .NET Hot Reload.

For additional details about this change, see the related announcement issue on GitHub.

Shadow-copying in IIS

We’ve added a new feature in the ASP.NET Core Module for IIS to add support for shadow-copying your application assemblies. Currently .NET locks application binaries when running on Windows making it impossible to replace binaries when the application is still running. While our recommendation remains to use an app offline file, we recognize there are certain scenarios (for example FTP deployments) where it isn’t possible to do so.

In such scenarios, you can enable shadow copying by customizing the ASP.NET Core module handler settings. In most cases, ASP.NET Core application do not have a web.config checked into source control that you can modify (they are ordinarily generated by the SDK). You can add this sample web.config to get started.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- To customize the asp.net core module uncomment and edit the following section. 
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->

  <system.webServer>
    <handlers>
      <remove name="aspNetCore"/>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModulev2" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
      <handlerSettings>
        <handlerSetting name="experimentalEnableShadowCopy" value="true" />
        <handlerSetting name="shadowCopyDirectory" value="../ShadowCopyDirectory/" />
        <!-- Only enable handler logging if you encounter issues-->
        <!--<handlerSetting name="debugFile" value=".\logs\aspnetcore-debug.log" />-->
        <!--<handlerSetting name="debugLevel" value="FILE,TRACE" />-->
      </handlerSettings>
    </aspNetCore>
  </system.webServer>
</configuration>

You require a new version of ASP.NET Core module to try to this feature. On a self-hosted IIS server, this requires a new version of the hosting bundle. On Azure App Services, you will be required to install a new ASP.NET Core runtime site extension

ASP.NET Core runtime site extension

Vcpkg port for SignalR C++ client

Vcpkg is a cross-platform command-line package manager for C and C++ libraries. We’ve recently added a port to vcpkg to add CMake native support (works with MSBuild projects as well) for the SignalR C++ client.

You can add the SignalR client to your CMake project with the following snippet (assuming you’ve already included the vcpkg toolchain file):

find_package(microsoft-signalr CONFIG REQUIRED)
link_libraries(microsoft-signalr::microsoft-signalr)

After this, the SignalR C++ client is ready to be #include’d and used in your project without any additional configuration. For a complete example of a C++ application that utilizes the SignalR C++ client, check out this repository.

Reduced memory footprint for idle TLS connections

For long running TLS connections where data is only occasionally sent back and forth, we’ve significantly reduced the memory footprint of ASP.NET Core apps in .NET 6. This should help improve the scalability of scenarios such as WebSocket servers. This was possible due to numerous improvements in System.IO.Pipelines, SslStream and Kestrel. Let’s look at some of the improvements that have contributed to this scenario:

Reduce the size of System.IO.Pipelines.Pipe

For every connection that we establish, we allocate two pipes in Kestrel: one from the transport layer to the application for the request and another from the application layer to the transport for the response. By shrinking the size of System.IO.Pipelines.Pipe from 368 bytes to 264 bytes (~28.2%), we’re saving 208 bytes per connection (104 bytes per Pipe).

Pool SocketSender

SocketSender objects (that subclass SocketAsyncEventArgs) are around 350 bytes at runtime. Instead of allocating a new SocketSender object per connection, we can pool them since sends are usually very fast and we can reduce the per connection overhead. Instead of paying 350 bytes per connection, we now only pay 350 bytes per IOQueue(one per queue to avoid contention). In our WebSocket server with 5000 idle connections we went from allocating ~1.75 MB (350 bytes * 5000) to now allocating just ~2.8kb (350 bytes * 8) for SocketSender objects.

Zero bytes reads with SslStream

Bufferless reads are a technique we already employ in ASP.NET Core to avoid renting memory from the memory pool if there’s no data available on the socket. Prior to this change, our WebSocket server with 5000 idle connections required ~200 MB without TLS compared to ~800 MB with TLS. Some of these allocations (4k per connection) were from Kestrel having to hold on to an ArrayPool buffer while waiting for the reads on SslStream to complete. Given that these connections were idle, none of reads completed and return their buffers to the ArrayPool forcing the ArrayPool to allocate more memory. The remaining allocations were in SslStream itself: 4k buffer for TLS handshakes and 32k buffer for normal reads. In preview3, when the user performs a zero byte read on SslStream and it has no data available, SslStream will internally perform a zero-byte read on the underlying wrapped stream. In the best case (idle connection), these changes result in a savings of 40 Kb per connection while still allowing the consumer (Kestrel) to be notified when data is available without holding on to any unused buffers.

Zero byte reads with PipeReader

Once SslStream supported bufferless reads, we then added the option to perform zero byte reads to StreamPipeReader, the internal type that adapts a Stream into a PipeReader. In Kestrel, we use a StreamPipeReader to adapt the underlying SslStream into a PipeReader and it was necessary to expose these zero byte read semantics on the PipeReader.

You can now create a PipeReader that supports zero bytes reads over any underlying Stream that supports zero byte read semantics (e.g,. SslStream, NetworkStream, etc) using the following API:

var reader = PipeReader.Create(stream, new StreamPipeReaderOptions(useZeroByteReads: true));

Remove slabs from the SlabMemoryPool

To reduce fragmentation of the heap, Kestrel employed a technique where it allocated slabs of memory of 128 KB as part of it’s memory pool. The slabs were then further divided into 4 KB blocks that were used by Kestrel internally. The slabs had to be larger than 85 KB to force allocation on the large object heap to try and prevent the GC from relocating this array. However, with the introduction of the new GC generation, Pinned Object Heap (POH), it no longer makes sense to allocate blocks on slab. In preview3, we now directly allocate blocks on the POH, reducing the complexity involved in managing our own memory pool. This change should make easier to perform future improvements such as making it easier to shrink the memory pool used by Kestrel.

BlazorWebView controls for WPF & Windows Forms

For .NET 6 we are adding support for building cross-platform hybrid desktop apps using .NET MAUI and Blazor. Hybrid apps are native apps that leverage web technologies for their functionality. For example, a hybrid app might use an embedded web view control to render web UI. This means you can write your app UI using web technologies like HTML & CSS, while also leveraging native device capabilities. We will be introducing support for building hybrid apps with .NET MAUI and Blazor in an upcoming .NET 6 preview release.

In this release, we’ve introduced BlazorWebView controls for WPF and Windows Forms apps that enable embedding Blazor functionality into existing Windows desktop apps based on .NET 6. Using Blazor and a hybrid approach you can start decoupling your UI investments from WPF & Windows Forms. This is a great way to modernize existing desktop apps in a way that can be brought forward onto .NET MAUI or used on the web. You can use Blazor to modernize your existing Windows Forms and WPF apps while leveraging your existing .NET investments.

To use the new BlazorWebView controls, you first need to make sure that you have WebView2 installed.

To add Blazor functionality to an existing Windows Forms app:

  • Update the Windows Forms app to target .NET 6.
  • Update the SDK used in the app’s project file to Microsoft.NET.Sdk.Razor.
  • Add a package reference to Microsoft.AspNetCore.Components.WebView.WindowsForms.
  • Add the following wwwroot/index.html file to the project, replacing {PROJECT NAME} with the actual project name:
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>Blazor app</title>
    <base href="/" />
    <link href="{PROJECT NAME}.styles.css" rel="stylesheet" />
    <link href="app.css" rel="stylesheet" />
</head>

<body>
    <div id="app"></div>

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

    <script src="_framework/blazor.webview.js"></script>
</body>
</html>
  • Add the following app.css file with some basic styles to the wwwroot folder:
html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
  • For all files in the wwwroot folder, set the Copy to Output Directory property to Copy if newer.
  • Add a root Blazor component, Counter.razor, to the project:
@using Microsoft.AspNetCore.Components.Web

<h1>Counter</h1>

<p>The current count is: @currentCount</p>
<button @onclick="IncrementCount">Count</button>

@code {
    int currentCount = 0;

    void IncrementCount()
    {
        currentCount++;
    }
}
  • Add a BlazorWebView control to the desired form to render the root Blazor component:
var serviceCollection = new ServiceCollection();
serviceCollection.AddBlazorWebView();
var blazor = new BlazorWebView()
{
    Dock = DockStyle.Fill,
    HostPage = "wwwroot/index.html",
    Services = serviceCollection.BuildServiceProvider(),
};
blazor.RootComponents.Add<Counter>("#app");
Controls.Add(blazor);
  • Run the app to see your BlazorWebView in action:

Blazor Windows Forms

To add Blazor functionality to an existing WPF app, follow the same steps listed above for Windows Forms apps, except:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:blazor="clr-namespace:Microsoft.AspNetCore.Components.WebView.Wpf;assembly=Microsoft.AspNetCore.Components.WebView.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <blazor:BlazorWebView HostPage="wwwroot/index.html" Services="{StaticResource services}">
            <blazor:BlazorWebView.RootComponents>
                <blazor:RootComponent Selector="#app" ComponentType="{x:Type local:Counter}" />
            </blazor:BlazorWebView.RootComponents>
        </blazor:BlazorWebView>
    </Grid>
</Window>
  • Set up the service provider as a static resource in the XAML code-behind file (such as MainWindow.xaml.cs):
var serviceCollection = new ServiceCollection();
serviceCollection.AddBlazorWebView();
Resources.Add("services", serviceCollection.BuildServiceProvider());
  • To workaround an issue with the WPF runtime build not finding Razor component types, add an empty partial class for the component in Counter.razor.cs:
public partial class Counter { }
  • Build and run your Blazor based WPF app:

Blazor WPF

Give feedback

We hope you enjoy this preview release of ASP.NET Core in .NET 6. We’re eager to hear about your experiences with this release. Let us know what you think by filing issues on GitHub.

Thanks for trying out ASP.NET Core!

75 comments

Comments are closed. Login to edit/delete your existing comments

  • Dariusz Daćko

    What with Blazor AOT? It was said that it can speed up Blazor WebAssembly. Are there some result now?

    • Daniel RothMicrosoft employee

      WebAssembly AoT is coming in .NET 6 as well and it should be available in soon in an upcoming .NET 6 preview. The performance improvements are looking really good! The tradeoff is a larger download size (~2x larger), a heavier toolchain (involves using Emscripten), and a longer publish time (minutes instead of seconds).

  • Pheakdey Tes

    Hi everyone
    What is computer specifications for running blazor hot reload?
    I tested with my pc it kind of slow.

    Thank

    • Daniel RothMicrosoft employee

      Hi Pheakdey. .NET Hot Reload should work on any machine supported by .NET 6 and the updates should be near instantaneous. Have you verified that hot reload is successfully enabled for your project and that the app isn’t just restarting? The output of dotnet watch should specific say that hot reload has been enabled and should explicitly state when a change has been hot reloaded. If hot reload does appear to be happening, but it is slow, please open a GitHub issue with details about your dev environment and we’ll take a look: https://github.com/dotnet/aspnetcore/issues.

  • Ali Borjian

    Blazer is great and Hot Reload support makes it so much better!

  • Junaid Bedford

    Hi if I only know Blazor and have no Xamarin knowledge nor knowledge of XAML can I develop a completely native (not hybrid) mobile app and will I have the ability to access native platform features (accelerometer or file system or other) when developing my mobile app in Blazor? Thanks

    • Daniel RothMicrosoft employee

      Hi Junaid. Yup, that’s what we’re enabling in .NET 6 with .NET MAUI & Blazor. You will be able to have a .NET MAUI app with a single full window BlazorWebView and do all of your UI work in Blazor. The Blazor components run natively on the device, so they have full access to native functionality through the .NET platform. You have the option to also use native UI controls in XAML if you want, but it isn’t required. We’ve been experimenting with this model for a little while now with the Mobile Blazor Bindings project, which is based on Xamarin: https://aka.ms/mobile-blazor-bindings. The learnings from the Mobile Blazor Bindings project inform what we’re doing with .NET MAUI & Blazor in .NET 6.

      • Junaid Bedford

        Hi Daniel,

        Thanks for your reply. This is awesome! I am loving this.

        On DevExpress video you mentioned that native access to platform APIs via .NET will take place over a SignalR connection (similar to Blazor Server) as well as for UI updates. Then you mentioned something called Blazor Native (which one could understand as being akin to React Native). Will one, or both, of these approaches be enabled in .NET 6?

        • Daniel RothMicrosoft employee

          Hi Junaid. For .NET 6 we’re enabling Blazor Hybrid apps, where you use a mixture of native and web technologies to build native apps. In a Blazor Hybrid app, your components run natively on the device, but they render UI using HTML, CSS, and an embedded browser control. That’s what the new BlazorWebView controls are for. SignalR and WebAssembly are not involved at all. Instead the components run directly on the device and we use a local interop channel between the Blazor components and the browser control to handle UI interactions and rendering.

          Blazor Native is a different approach, where you no longer use a browser control. Instead you use Blazor components that map directly to native UI elements. This is similar to what existing cross-platform offerings like React Native and Xamarin do, but instead of using JSX or XAML, you would use Razor and Blazor components. We’ve been experimenting with what Blazor Native might look like in the experimental Mobile Blazor Bindings project, but it isn’t something we plan to deliver for .NET 6.

          • Junaid Bedford

            Thanks Daniel and for clarifying that one could use Razor and Blazor components instead of XAML for a possible future Blazor Native approach.

            I really like where Blazor is going following a similar path to React and React Native.

  • Aditya Manthena

    Is there any plan to add Global Exception Handling for Blazor applications? Something like an OnException event for Blazor components?

  • Rod Macdonald

    3 Q’s if I may:

    Is it safe to assume Blazor code developed to run via BlazorWebView will be easy to port to MAUI + Blazor?

    How would MAUI + Blazor apps be distributed?

    As Blazor gets ported to more use situations e.g. desktop, is there likely to be a scenario where Blazor Server could be made to work without SignalR?

    • Daniel RothMicrosoft employee

      Hi Rod,

      Is it safe to assume Blazor code developed to run via BlazorWebView will be easy to port to MAUI + Blazor?

      Yes, you should be able to reuse the same components with the upcoming BlazorWebView for .NET MAUI. The component model is the same. To ensure your components work cross-platform with .NET MAUI and on the web, you should take care to insulate your components from platform specific concerns. For example, a component that calls into Windows specific APIs in a WinForms or WPF app will need to do something different when running in a .NET MAUI app on macOS. Typically this can be done using service interfaces that then have different injected concrete implementations on different platforms.

      How would MAUI + Blazor apps be distributed?

      The deployment and distribution story for .NET MAUI is still being worked out, but the intent is to provide as much flexibility as possible. If you have specific requirements here, please raise them in an issue on the https://github.com/dotnet/maui repo.

      As Blazor gets ported to more use situations e.g. desktop, is there likely to be a scenario where Blazor Server could be made to work without SignalR?

      The BlazorWebView works in a very similar way to how Blazor Server works, except instead of a SignalR connection over the internet it uses a local interop channel that talks directly to the embedded web view control. For web apps, we don’t have any plans to remove Blazor Server’s dependency on SignalR. If you think this is something we should consider, let us know by creating a GitHub issue with more details about your scenario: https://github.com/dotnet/aspnetcore/issues.

      • Rod Macdonald

        Hi Daniel, thank you for the comprehensive reply, appreciated.

        I’m not sure if our previous dialogue on UI got chopped up (I disconnected from GitHub as my specific UI request got binned whilst I was getting plagued with a bunch of unrelated stuff) so not sure if you ever got my response to some of your Q’s on that. You weren’t so keen on creating design tools as I recall but were good enough to ask what I was seeking. I subsequently took a look at Radzen and was blown away. If one could truly position and style controls with that, build that into VS. Then, taking that a step further, and I love the technologies of WinForms and WPF (use the former big time), but I really do hope MS will park these frameworks up and re-purpose XAML as a lightweight and agile ‘UI extension’ of HTML (SVG/SGML?) to compete with Flutter, throwing out any non-UI object graph XAML.

        I believe such a UI stack would rule the world, not that I’m bias 🙂

  • Ben Hayat

    Hi Dan;

    Could you please bring us up to date on the progress of “Blazor Wasm AOT” compilation feature that is slated for .Net 6?
    What we should expect and what not to expect for .Net 6?

    Thank you in advance!
    ..Ben

    • Daniel RothMicrosoft employee

      It’s coming! We almost had it ready to preview with .NET 6 Preview 3, but we hit some snags with packaging the toolchain. I expect we’ll have something to try out in the next .NET 6 preview update. You will be able to ahead-of-time (AoT) compile your Blazor WebAssembly apps to WebAssembly when publishing to get a substantial performance boost. The tradeoff is a larger download size (~2x larger), a heavier toolchain (involves using Emscripten), and a longer publish time (minutes instead of seconds). The toolchain will also enable linking in native WebAssembly dependencies. Related work is tracked by https://github.com/dotnet/runtime/issues/44316 and https://github.com/dotnet/runtime/issues/44636.

      • Ben Hayat

        Thank you Dan;

        The tradeoff is a larger download size (~2x larger),

        Is the AoT optional, or mandatory?
        The biggest drawback as of now, is the load time, and not performance during application life cycle.
        For that I plan to use “Lazy loading” and break the app into modules and sub modules. But if the AoT is going to increase the load size, I might stay with conventional system.

        • Daniel RothMicrosoft employee

          Hi Ben. Using WebAssembly AoT will be optional. You will still be able to publish using the interpreter like you can today.

  • Jose Cuevas

    Does Hot Reload support razor syntax changes? I tried updating an HTML heading with no success. Hot Reload detects a change however nothing is refreshed. I have to use Ctrl+R to restart the app and show the change. However, I can update any C# code and comment out razor components and Hot Reload refreshes the running app just fine.

    • Daniel RothMicrosoft employee

      Hi Jose. Yes, .NET Hot Reload works with all of our C# related code changes, and that includes .razor and .cshtml files, which get compiled into C# classes. Is the HTML heading you changed in a .cshtml or .razor file? Changes to static HTML files won’t be hot reloaded – but we should refresh the browser for you for those. If you’re having issues with hot reloading changes from a Razor file, please file a GitHub issue with the repro steps and we’ll take a look: https://github.com/dotnet/aspnetcore/issues.

      • Jose Cuevas

        Hi Daniel.

        I appreciate your response, I was able to pinpoint why my html element wasn’t updating within a Razor component in a Blazor WASM app using the latest preview. It turns out the @bind razor directive breaks html hot reloading. I’ve submitted an issue https://github.com/dotnet/aspnetcore/issues/31702

  • Darrell Tunnell

    I’ll be “that guy” then :-). Whats the story for rendering a blazor web view on linux too? WPF and Windows Forms are great windows only vehicles. I use wasm because of its amazing portability and ability to run anywhere. Blazor wasm lets me use c# to create wasm apps. If I could release my blazor wasm application in a vehicle that runs natively on any platform (which includes linux) then this would be worth transitioning to. All the while its windows or mac only there is no real point really – all customers (including linux) users can currently use the website version of the app – a move to native would only descriminate against any linux users for which that experience is not available.

    • Daniel RothMicrosoft employee

      Hi Darrell. We are also building a BlazorWebView for .NET MAUI to support cross-platform scenarios. Initially .NET MAUI will support Windows, macOS, Android, and iOS, but once it supports Linux it will support Blazor on Linux too. Note that your Blazor components don’t run on WebAssembly when you use a BlazorWebView. Instead your components run natively on the device and then communicate with the browser control using a local interop channel to handle rendering and UI interactions.