Aspnetcore: AoT compilation

Created on 25 Jan 2018  ·  72Comments  ·  Source: dotnet/aspnetcore

Compile everything to WebAssembly

Components Big Rock External Design affected-most area-blazor blazor-wasm blocked enhancement severity-major

Most helpful comment

@danroth27 I really appreciate the explanation and the position you're in with trying to get .NET 5 ready along with everything else. Some comments/questions:

The first step to AoT is to move Blazor WebAssembly to use the same core .NET libraries that are used by .NET Core, which should also help performance

I assume you're referring to switching to CoreFX from the Mono mscorlib? I think that's an excellent move if so given the many published performance benchmarks showing CoreFX outperforming Mono (and NetFX for that matter) significantly.

Then we need to work out how to make AoT work well with IL linking.

Yeah linking has been a major hurdle for awhile now as has been discussed here. Still, Uno has managed to make a toolchain and strike a balance between interpreted and compiled that can get app sizes in the ~10MB or low teens range. I would have thought we'd at least have a PoC for this on the Blazor side, just to start gauging performance metrics. It's not having any idea what degree performance will improve that is most concerning right now.

We also plan to look at startup performance of the runtime itself once it is downloaded.

The DOM building piece of this needs to be carefully looked at too. Loading an empty Blazor app takes 1-2 seconds on my desktop and a couple more on mobile. Having lived in the Angular world I'm used to seeing "Loading..." every time and find the base startup time to be fine. The bigger problem is the excruciatingly slow speeds building complex DOMs. Even DOMs with 1000-2000 elements add as much as 5-10 seconds for the initial load, and interactivity involving complex items also adds significant lag. I don't see this being talked about much and I worry that (1) AOT is not going to solve this because it's endemic to WASM/JS interop and the way strings are exchanged between the two; and (2) the rendering/diffing mechanism in Blazor is so baked in now that it's too late to change it into something that would be high performance.

The current thinking is that we will make the AoT toolchain available to developers so that you can decide how much of your app you want to AoT and then the app will run in a mixed mode,

Exactly like Uno is already doing,...

So here's my reaction and analysis to all this, and I want you and everyone else to understand that I'm coming at this as someone who's probably as big of a .NET and Microsoft fan as there ever has been. Blazor was introduced to the world as a framework for using _webassembly_ to bring .NET back to the browser. I was ecstatic when I learned about it. But it's been over two years now since it was first introduced for preview and the webassembly piece is still not ready for consumer applications because of the severe performance issues. Meanwhile lots was invested in server-side (whose place I'm still not entirely sure of) and now maybe mobile through Xamarin, but the WASM can keeps getting kicked down the road again and again.

.NET has lost so much ground as a frontend web platform since SPAs took over and Silverlight died thanks to Chrome banning plugins. Blazor could have changed all that. But I can't tell right now if Blazor WASM is really intended by Microsoft as the strategic game changer it could be or just a curiosity for fanboys like myself. But fanboy or not, as a business owner if I'm picking a frontend framework today for a new project or a rebuild of an old one, how do I justify to my backers that Blazor is the way to go, over React or Angular? When I list the pro's and con's, what am I left with as a pro other than I like C#? The cons, on the other hand, keep mounting.

So I'm very disappointed and a little demoralized. It's not just having to wait longer, it's that there are still many doubts about whether this tech is ever going to be viable, and I for one had been waiting to see AoT so I could make that determination.

I'm not expecting you guys to change your roadmap or really be in a position to alleviate any of these concerns today, but I thought they were worth airing. I desperately want this to succeed and would love nothing more than for .NET to reclaim its place as the king of interactive web apps. But if I had to put money on it today, it's not looking like a good bet. Please prove me wrong!

All 72 comments

Follow up on status of mono-wasm

Do you know an issue where we can track progress on this?

Current interpreter mode is very slow.
https://dotnetfiddle.net/JUpsRT

.NET 300 ms
WASM: 13155 ms

Yup, we think this more a result of nothing being optimized yet than an indication that we should move to AoT at this point, but we'll know more as the IL interpreter and AoT support matures.

@danroth27 From what I can tell the performance difference between the Mono IL interpreter and the current mono.wasm version is about 5-10x. Overall mono.wasm is about 50-80x and the IL interpreter about 10x slower than a native .NET Core console application.

So the interpreter is currently still not very fast overall and WebAssembly adds even more overhead on top of that.

I would assume that AOT probably still has better chances of speeding things up, but you are right that it's most likely too soon to rule out the interpreter, as most web applications don't even have such high performance demands and will most likely be fine with an interpreted version.

AOT being more efficient doesn't only matter to intensive applications. It also matters for mobile and other low end platforms, especially when you consider battery usage.

Is there currently any feasible way to enable AoT compilation for Blazor projects? I keep reading blog posts that claim Blazor already has an AoT mode; if this is true, could someone please point to an article explaining how to enable it?

@TheFanatr the AOT compilation is dependent on mono supporting this feature. As far as I can tell the last update on the topic was from @migueldeicaza in the Blazor Gitter.

Miguel de Icaza (2018-06-08 19:01):
We are working on it. What happened is this:
The interpreter is using “emscripten” that has a fairly complete libc that we can rely on. And our AOT engine was built on pure LLVM, which requires from us to write the full libc. The latter is the ideal place, because we get native linkers and immedite llvm support and so on. But woudl send us down the path of having to write that libc.
So for the short term, we are moving to emscripten the AOT compiler, make sure that we keep the compatibility. The downside though is that the emscripten tooling is older, so many of the better pieces like the LLVM linker are not available. So we are working through those things.
Basically, we had something done, but we had to start from scratch to work with what we have without forving us to write and emulate everything on our own. We could have attempted to blend those two, but that is also a major effort. So we think we can do emscripten for now via some artful hacks here and there.

So in short, they are working on it, but there isn't a good option to do this with the current public builds.

Some pretty great progress has just been reported in CoreRT !!

https://github.com/dotnet/corert/issues/4659#issuecomment-425690500

anyone have an idea on what's blocking this? i might be willing to put in a few trillion manhours to see AOT happen sooner than later now that clientside blazor has been committed to by the powers that be at Microsoft. AOT is going to be really important if we want to develop ( excellent ) PWAs with Blazor.

@honkmother AoT is being worked on by the mono.wasm folks in the https://github.com/mono/mono repo. I'm sure they would be thrilled to have your help! This issue tracks consuming their work once it is ready.

I think I have a somewhat related question but it isn't well thought out and badly worded- I've been experimenting with ILRepack and Blazor, and managed to package most of the dlls together into a single monolithic blob. Do you guys intend to at any point package the common libraries together as a single dll?

@honkmother We don't currently have any concrete plans to do so, but we'd be interested to hear the results of your experimentation.

I was able to merge most of them together by just using ILRepack on the /dist/bin/ output, and including System.Core.dll. Startup times were improved after combining most of the libraries, but it introduced a lot of head-scratching bugs that I have no idea how to solve; and of course you're losing out on the ability to rely on caching for updated pieces of code without having to download the entire blob again.

So have there been any developments on this or at least an ETA? Server-side is working quite well but client-side WASM performance through the interpreter is still unacceptable as soon as the DOM gets reasonably complex.

I don't think so, the AOT on the mono repo still seems to be a WIP; I heard we'll have it by Q1 of 2020 but I don't know if that's for certain; which is sad because I have a very nice PWA set up with client-side but it has some performance issues that AOT would probably alleviate without needing dirty hacks.

In the meantime are some things you can do to alleviate the pain there, namely using virtual DOM and/or using RenderTreeBuilder directly so that you're not rendering everything at once and have some control over what's going on.

Well, I was also wondering if anything has changed in light of the announcement a few months ago about .NET 5. Interesting quote there:

The Blazor project is already using the Mono AOT. It will be one of the first projects to transition to .NET 5. We are using it as one of the scenarios to prove out this plan.

Do they know something we don't?

In the meantime are some things you can do to alleviate the pain there, namely using virtual DOM and/or using RenderTreeBuilder directly so that you're not rendering everything at once and have some control over what's going on.

Indeed. I am making an MVVM framework from scratch inspired by WPF and one of the first things I do is override ShouldRender to turn off Blazor's automatic render triggers and instead rely on property changes to tell components when to re-render. In fact one HUUUUGGGE performance improvement comes by updating styles through JS interop, rather than StateHasChanged, whenever possible.

Nonetheless, I'm having issues when large DOMs need to be generated up front - for example, a complex list or data grid. Server side is fine, but client side takes 5-10 seconds sometimes just to initially render.

What we really need is a VirtualizingPanel like in WPF. I have been thinking extensively about how this could be implemented in Blazor and JS interop, but a complete solution still eludes me. In WPF it works because the framework is responsible for measuring every visual element and reporting its size. Even with JS interop I'm not sure the same thing is possible, and I've yet to see a good generalized solution for this in any web framework.

SyncFusion has some virtualization components, namely a list view - no idea how they work but I am using them. Might want to check them out.

There is also https://github.com/SamProf/BlazorVirtualScrolling which is worth looking at as well.

Oh yes I saw that. Glad to know it works well for you. It does have the significant limitations of needing a uniform item height and that the height be known in advance. But that could be an interim solution.

Can someone tag this issue with the blazor-wasm tag? Its hard to find this issue amidst all of the server side (or hosting agnostic) Blazor issues.

And for those looking for an overview for the Mono WASM AOT work being done, I found this link:
https://github.com/mono/mono/projects/11

Your wish is my command 😆

Thanks that's very helpful!

Is it possible to get even the vaguest of estimates for when we might be able to start using AOT compiled WASM with Blazor, even experimentally? 6 months? A year? Has anyone on the Blazor team actually successfully gotten it working even in an ad-hoc fashion?

It's a little risky to start investing a lot of time in, or plan around, client-side Blazor when we still really don't know what the end product will look like. As good as server-side is we really need a reliable and performant client-side version for this to be viable.

I have posted this question here https://github.com/mono/mono/issues/10222 but got the answer that it is a wrong place. Reposting here:

It was announced that Blazor WASM will be released in May 2020. Can we assume that it will be native WASM application at this time? What is the correct answer?

  1. Yes.
  2. We will try, but we are not sure.
  3. No, it will be available in November 2020 with .NET 5.0.
  4. No, and we don't have any roadmap just yet.

For all Blazor fans two things are very important:

  • Runtime speed - interpreter is to slow in some use cases.
  • Download size - hopefully you will be able to achieve WASM size similar to current .NET DLLs and we will be able to remove mono.wasm completely (I believe this file contains IL interpreter only - am I right?).

I'm a big fan of Blazor since the beginning. I know that Blazor server side has some advantages for some people but we are all waiting for real revolution - fast and reliable Blazor in the browser.

Thank you guys for your hard work!!!

@Andrzej-W This might be a bit misleading to anyone who skims through this and assumes that November 2020 is the canonical release.

Personally I have heard it is supposed to come out officially around Q1 of 2020.

Realistically there is nothing preventing us from implementing it into our build processes right now as far as I know beyond the bloated executable size and the fact it is not supported by Microsoft as of yet.

Realistically there is nothing preventing us from implementing it into our build processes right now as far as I know beyond the bloated executable size and the fact it is not supported by Microsoft as of yet.

Has anyone tried this? I think it's important for us to at least have a proof of concept so we can see how it performs compared to interpreted and compared to server-side. I know exe size is something the mono team is working on, and it is important, but app speed is king. (And compilation time is really irrelevant IMHO because we will be doing debugging server-side and only compile to native WASM for release. Compilation time for webpack can be pretty attrocious too).

At .NET Conf we announced that the first release of Blazor WebAssembly is planned for May 2020. For this first Blazor WebAssembly release we expect that the runtime will still be based on the IL interpreter that we are currently using.

The .NET runtime team is working on ahead of time compilation support for compiling directly to WASM. This approach has the benefit of improving runtime performance, but at the expense of app size.

For the initial release of Blazor WebAssembly in May we are exploring running the IL interpreter in a mixed mode, where hot paths have been compiled to WASM but the rest of the app is .NET assemblies. This provides a nice compromise between runtime performance and app size. However, it's not clear yet if this will land in time for May.

Longer term, we want to provide an SDK that gives the app developer control which parts of their app are compiled directly to WASM. There isn't a roadmap yet for when such an SDK will be available.

@lewing @richlander

Thank you @danroth27 for explanation. Download size can be partially masked by server side prerendering - make sure this https://github.com/danroth27/ClientSideBlazorWithPrerendering will work in all future Blazor (pre)releases.

@danroth27 thanks for the update! One clarification question - does "the .NET runtime team" refer to the Mono team, CoreRT, .NET 5, or something else?

@legistek They are all one team now :smile:. The tech though is based on the Mono runtime.

Oh, right I forgot. ;D What I was getting at was whether mono/wasm/10222 was the right issue/repo for info on this topic.

@legistek Yup, all the .NET WASM working is currently happening in the mono repo.

I've built a pretty complex app running server side Blazor now, and it's working very well. (WASM through the IL interpreter, however, is so slow as to be unusable).

I'm really dying to know how it would run with compiled WASM.

If we ignore download size or compile time just for the time being, is there any way of AOT compiling a Blazor app to WASM yet and trying it out? Over at the mono repo (https://github.com/mono/mono/issues/10222) people are posting some examples of AOT with other platforms like Uno, but I've yet to see a Blazor example let alone instructions on how to do it.

I realize the build process would be completely ad hoc at this point, but is it possible even in principle just so we can get even a rough sense of the performance difference? I like server side for debugging and demoing but I don't know if it's viable for a production deployment at scale. Thus I'm hesitant to do much more work on this project until I know that performance on AOT WASM will be good. I have to imagine there are a lot of people in the same boat.

Just to follow up, I wound up trying out the Uno WASM bootstrap using WSL (described here) and it really works quite well. This issue here is still marked as BLOCKED and while I know they're still working on reducing payload size that doesn't seem like it should be blocking work on an AOT build chain for Blazor, even if it is just Linux for now. Is that going on and if not what is the Blazor team waiting on from the Mono team before starting that?

@legistek did you build your app or something else? How much better is the performance? Do you have some metrics to share? Asking out of curiousity.

I built a subset of my app and then just ran some performance metrics since I couldn't run the whole thing without Blazor bootstrapping.

For math (random number generation and simple arithmetic) I found AOT to be about 40x faster than interpreted.

What I was really interested in were things I knew would be inefficient like reflection and string manipulation. My app has a custom data binding framework similar to WPF so I tried setting up a complex data binding and changing the value to a random string 10,000 times. Here were the results:

Mono Interpreted IL: 2.49s
Full AOT (Chrome): 0.702s
Full AOT (Firefox): 0.5s
Native: 0.067s

So basically we have a worst case scenario of AOT being about 4x as fast as interpreted IL, but a best case scenario of as much as 40x.

I think that's probably to be expected.

Unfortunately this still doesn't tell us how well Blazor AOT will do vs interpreted, but I'm a little pessimistic that it's going to be on the lower side (4-5x) because Blazor is presumably doing a lot of string manipulation to build the DOM, and also a sophisticated SPA will be doing a lot of JSON API calls (which of course use reflection and strings extensively). But really we can't be sure until we can actually try out a real Blazor app with AOT.

I would imagine the performance will be remarkably improved in the near future as browser vendors start to take WebAssembly more seriously.

I think AOT merits a lot more investigation sooner than later because Blazor will likely live or die by the reputation of it's clientside implementation in WASM.

Projects like https://d07riv.github.io/diabloweb/ prove without a doubt that WebAssembly is more than capable of handling itself but I have yet to see an equally impressive proof of concept running on Mono+WASM.

This issue is open for two years.. Is there any progress?

@partyelite Yes, there has been progress. There is an implementation of AoT compilation to WASM in the https://github.com/mono/mono repo and the runtime has been updated to support executing a mixture of .NET IL and compiled WASM files. However, the AoT support will not be ready for the upcoming May release. We will revisit shipping it for .NET 5.

I tried the AOT compilation option Dan is referring to and it works well with Uno.

What I'm still scratching my head about is why there isn't at least a PoC of it working with Blazor yet? I realize the toolchain is all still Linux and the output files are much larger than we ultimately want, but what is preventing making an example of a Blazor app working with AoT so that we can gauge performance and feasibility?

I'm not sure if this is related, but on the Syncfusion repository there was a performance issue reported a while ago (https://github.com/syncfusion/blazor-samples/issues/50), said to be caused due to the slow performance of mono.

In my analysis, the performance issue drills down to calling js_to_wasm:
grafik

Is this something that will be solved by this and the mono team? Or is this something unrelated?

@Herdo it might be related to this: https://github.com/dotnet/aspnetcore/issues/5617

Check your web console log to see if it's GCing excessively. This seems to be baked into the WASM Mono runtime and needs to be configurable IMO.

@honkmother ,
Can you please share more Infos on how you succeeded in packaging Blazor DLLs with ILRepack? I used ILRepack.MSBuild.Task as detailed here. Packing succeeds but when I run the application I always get this error:

WASM: System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies.

It appears that packaging breaks something, or at list prevents a correct bootstrap of the application.

hmm AOT is in UNO. Can you C&P this solution?

.Net 5 won't support AoT Compilation for Blazor?

It's crossed off the roadmap too.

I'd like to hear official comment before jumping to conclusions, but if true this is very bad news that not just affects Blazor but would force me to reevaluate .NET itself as a frontend platform.

There's been no reported activity in months on the Mono side of this either:
https://github.com/mono/mono/issues/10222

Maybe it's time to cut losses and focus on CoreRT instead.

@ram16g @legistek We're working to improve Blazor WebAssembly runtime performance in .NET 5 (and beyond). AoT is still on our longer-term roadmap, but it's going to take longer to deliver than we have time for in .NET 5. The first step to AoT is to move Blazor WebAssembly to use the same core .NET libraries that are used by .NET Core, which should also help performance. That's the work that is happening right now. Then we need to work out how to make AoT work well with IL linking. At this point, we think we'll need until first quarter next year (early previews of .NET 6) to make the first previews of .NET AoT support for WebAssembly publicly available. But even without AoT, we still expect to deliver significant performance improvements for Blazor WebAssembly in .NET 5.

Hello @danroth27, the overall performance is right now not so much to my concern but what about the initial startup performance? It takes 2-3 seconds every page visit till the actual page loads, till the runtime is loaded the DLLs compiled etc. Will there be improvments without AOT? Or do we need to rely on prerendering?

Hi @MichaelPeter. The initial page load time is dominated by downloading the app and starting the runtime. AoT won't really help that. AoT is intended to improve runtime performance, not reduce the app download size. For JIT based runtimes AoT can improve startup performance because you avoid the need to JIT at runtime, but Blazor WebAssembly uses an IL interpreter based runtime without any JIT support.

In all likelihood, AoT will actually make the app larger to download, because .NET IL is a more compact format than its natively compiled representation. So using AoT will likely result in a tradeoff between speeding up runtime performance at the expense of increased download size. The current thinking is that we will make the AoT toolchain available to developers so that you can decide how much of your app you want to AoT and then the app will run in a mixed mode, where some of the app still runs as .NET IL, while the performance critical paths are precompiled to WebAssembly.

To improve the app starup performance we are looking at further improvements to the .NET IL linker and also doing work to the core framework libraries to make them more linkable. We also plan to look at startup performance of the runtime itself once it is downloaded.

@danroth27 Are there any issues that I can follow about the progress on the app startup performance? This is at the moment my biggest concern about blazor.

@danroth27 :+1: Thank you very much for the info, I mostly use Blazor in LAN envoirements where Download times should be almost zero and thought the Browser is caching the. Net DLLs anyway. But in a Startup Issue I would also be very interested.

Please note that startup times for WebAssembly-based applications like the Blazor interpreter can be dependent on whether the browser is properly caching the files. If the web-server hosting your application is configured incorrectly or the file has changed or the browser is otherwise unable to cache the application, it will have to recompile it from scratch every time you start the app. Under ideal circumstances, the browser is able to cache it so future visits after your first visit will start much faster.

You can see https://v8.dev/blog/wasm-code-caching for information on this. Firefox has a similar mechanism, and I believe Safari does as well but I'm not certain.

@danroth27 I really appreciate the explanation and the position you're in with trying to get .NET 5 ready along with everything else. Some comments/questions:

The first step to AoT is to move Blazor WebAssembly to use the same core .NET libraries that are used by .NET Core, which should also help performance

I assume you're referring to switching to CoreFX from the Mono mscorlib? I think that's an excellent move if so given the many published performance benchmarks showing CoreFX outperforming Mono (and NetFX for that matter) significantly.

Then we need to work out how to make AoT work well with IL linking.

Yeah linking has been a major hurdle for awhile now as has been discussed here. Still, Uno has managed to make a toolchain and strike a balance between interpreted and compiled that can get app sizes in the ~10MB or low teens range. I would have thought we'd at least have a PoC for this on the Blazor side, just to start gauging performance metrics. It's not having any idea what degree performance will improve that is most concerning right now.

We also plan to look at startup performance of the runtime itself once it is downloaded.

The DOM building piece of this needs to be carefully looked at too. Loading an empty Blazor app takes 1-2 seconds on my desktop and a couple more on mobile. Having lived in the Angular world I'm used to seeing "Loading..." every time and find the base startup time to be fine. The bigger problem is the excruciatingly slow speeds building complex DOMs. Even DOMs with 1000-2000 elements add as much as 5-10 seconds for the initial load, and interactivity involving complex items also adds significant lag. I don't see this being talked about much and I worry that (1) AOT is not going to solve this because it's endemic to WASM/JS interop and the way strings are exchanged between the two; and (2) the rendering/diffing mechanism in Blazor is so baked in now that it's too late to change it into something that would be high performance.

The current thinking is that we will make the AoT toolchain available to developers so that you can decide how much of your app you want to AoT and then the app will run in a mixed mode,

Exactly like Uno is already doing,...

So here's my reaction and analysis to all this, and I want you and everyone else to understand that I'm coming at this as someone who's probably as big of a .NET and Microsoft fan as there ever has been. Blazor was introduced to the world as a framework for using _webassembly_ to bring .NET back to the browser. I was ecstatic when I learned about it. But it's been over two years now since it was first introduced for preview and the webassembly piece is still not ready for consumer applications because of the severe performance issues. Meanwhile lots was invested in server-side (whose place I'm still not entirely sure of) and now maybe mobile through Xamarin, but the WASM can keeps getting kicked down the road again and again.

.NET has lost so much ground as a frontend web platform since SPAs took over and Silverlight died thanks to Chrome banning plugins. Blazor could have changed all that. But I can't tell right now if Blazor WASM is really intended by Microsoft as the strategic game changer it could be or just a curiosity for fanboys like myself. But fanboy or not, as a business owner if I'm picking a frontend framework today for a new project or a rebuild of an old one, how do I justify to my backers that Blazor is the way to go, over React or Angular? When I list the pro's and con's, what am I left with as a pro other than I like C#? The cons, on the other hand, keep mounting.

So I'm very disappointed and a little demoralized. It's not just having to wait longer, it's that there are still many doubts about whether this tech is ever going to be viable, and I for one had been waiting to see AoT so I could make that determination.

I'm not expecting you guys to change your roadmap or really be in a position to alleviate any of these concerns today, but I thought they were worth airing. I desperately want this to succeed and would love nothing more than for .NET to reclaim its place as the king of interactive web apps. But if I had to put money on it today, it's not looking like a good bet. Please prove me wrong!

I have to say that I'm in the same situation as @legistek. I'm using Blazor from version 0.1 and I'm a big fan of this technology. Of course for some of us it is nice to have an option to run Blazor on the server. It is also an interesting option to have Blazor on mobile, but I truly believe that WebAssembly implementation should have the highest priority. It is the game changer, it is the future.

@danroth27 for blazor the JSON deserialization speed is extremely slow for larger lists of objects, is there any guidance on how to do this fast rather than using the currently slow interpreter way.

I find this to be the worst performance hit in blazor if rest apis are being used and the datasizes are larger whereas javascript doesn't get impacted by the size in anywhere near the same way.

If it requires a manual deserialisation process that would be fine for those larger lists, just wondering if there is some guidance on this. Ideally we'd be able to AOT the deserialisers?

To get the startup time down, I suggest lazy loading. Meaning only load dll’s that are necessary for thaT specific view or page. That would indeed speed up the startup

@ram16g @legistek We're working to improve Blazor WebAssembly runtime performance in .NET 5 (and beyond). AoT is still on our longer-term roadmap, but it's going to take longer to deliver than we have time for in .NET 5. The first step to AoT is to move Blazor WebAssembly to use the same core .NET libraries that are used by .NET Core, which should also help performance. That's the work that is happening right now. Then we need to work out how to make AoT work well with IL linking. At this point, we think we'll need until first quarter next year (early previews of .NET 6) to make the first previews of .NET AoT support for WebAssembly publicly available. But even without AoT, we still expect to deliver significant performance improvements for Blazor WebAssembly in .NET 5.

Hello everyone and @danroth27, how much will this improve the speed of startup (assuming all stuffs are cached)? What can i do to help deliver aot by november? I don't like to use angular anymore. ahahahaha I'm willing to offer free coding just to speed this up. I dont really care about the initial download size because it will just be cached. Users are frequent visitors. angular can startup instantly when files are cached.

@hoksource We don't have exact numbers on how the perf characteristics will change, however if you try out the previews in 1-2 months you should be able to find out.

@hoksource We don't have exact numbers on how the perf characteristics will change, however if you try out the previews in 1-2 months you should be able to find out.

@SteveSandersonMS ok so
to contribute my goal will be to be able to do the following:

Option 1: Direct approach (deal with the problem directly):
[ ] learn to compile mono project
[ ] learn to compile asp.net blazor project
[ ] learn to compile an asp.net blazor with webassembly
[ ] learn to compile the blazor client program to webassembly completely aot (is mono->webassembly aot done? can it combine all reference binaries into 1 wasm file?)
[ ] check if mono can compile a whole webassembly project to aot web assembly.
[ ] figure out how to support all missing c#/.net language to webassembly
[ ] figure out the optimal linking structure to convert all dll into 1 wasm or multiple wasm files
[ ] figure out the best way to do above weighing file size and performance
[ ] learn/design linking and merging binaries to 1 webassembly or allow lazyloading with partial assemblies
[ ] have different set of solutions, choose the top few best solutions, present them to you guys. via some public/private repository branch from the current project

Option 2: (deal with the problem indirectly)
[ ] i'll do minion small simple tasks like small/easy modules/designing/documentations, have faith that greater engineers/designer can focus/direct their resources on the direct approach stated on option 1 before nov .net 5 release.

  • additional question. are all reference libraries supposed to be open source? i've code quite a few libraries, but im not sure if i want to expose all of them publicly.

But i think option 1 would be the best option since i would not be redoing some other stuffs that one of you guys are doing. Kindly confirm if i missed out anything.

@hoksource Thanks for your willingness to get involved. Currently the only practical option is option 1, since the ASP.NET Core team is fully occupied with other work. I know that is a huge number of things you'd have to figure out, but hopefully that helps to explain why it's not something we're able to just slip into the .NET 5 milestone :) It sounds like you do have good insights into the range of things needed here.

additional question. are all reference libraries supposed to be open source? i've code quite a few libraries, but im not sure if i want to expose all of them publicly.

It's completely up to you what you make open source and what you don't. ASP.NET Core itself is open source, but you can build closed-source things on top of it if you want. We can only include open source things in our repo here.

For JIT based runtimes AoT can improve startup performance because you avoid the need to JIT at runtime, but Blazor WebAssembly uses an IL interpreter based runtime without any JIT support.

Out of curiosity: would JITting on the client be a practical alternative to interpreting/going full AoT?

Hi folks! Just been doing some talking with some teams and things. Seems this is pretty much essential for libraries such as SkiaSharp. The main part of SkiaSharp is a native library and the output is basically a .a file that needs to be statically linked in. We _could_ potentially build a dynamic native library, but does Blazor even support that?

FYI, it is currently possible to static link a native library into the runtime. It's not something I would recommend as it's non-trivial, but you could do that and then p/invoke into the statically linked library once all the pieces are there. I don't know if we have any test cases that do it yet so it may require some additional infrastructure that isn't shipping in Blazor yet. You'd have to compile your own dotnet.wasm/dotnet.js to integrate with your Blazor builds which isn't for the faint of heart.

Dynamic native libraries are another matter, my understanding is that the tooling for that in wasm in general is not great right now, before you even get to the question of whether Blazor supports them.

I found out last year that dynamic linking is not a viable solution at all at this point. Emscripten implies that the "main" wasm module includes all possible combinations of system libraries any dynamic library would like to use. This makes for a very large common wasm module to start with.

I tried using that approach with Uno.SkiaSharp for a while, but it was rough and put that aside (at which point @vargaz probably refrained himself to say "told you so" 😂).

The Uno bootstrapper is now able to use static linking (directions here) and P/Invoke through WSL on Windows, and since it's using the same execution paths the internal System.Native interop uses, it's pretty stable now. You can even interop easily with rust modules that way.

I did some reading, only the .net runtime is converted to wasm. All dlls are downloaded and parsed on startup. it looks like the wasm runtime being used is mono. Their goal now is to use .net core runtime instead.

The current full aot compiler is being done by mono, but I'm not sure if a full aot with .net core should be the path/way. (No idea what I'm saying here. needs expert )

Internet says .net core runs twice faster than mono for computational intensive tasks. The startup is io related, 1st downloading the .dll binaries and dependencies. (Multiple files) parsing them to memory. Then starting the blazor wasm client app on top of it. The downloading takes a while (but can be cached) and the parsing takes a while. The aot compiler also does not know which are the dependencies of blazor and which are app specific. It will be messy if you always set which dll to include in aot wasm. So a full aot looks nice. (But it will be faster with .net core runtime implementation instead of mono? Not sure again about this one) im also not sure if the design/implementation of full aot wasm compiling is done with mono or .net runtime. Also not sure about the progress

@danroth27 Is there any progress ?

Will it be available in .NET 5 ?
It would be nice to have some pre-release to check this functionality also ;)

@redradist AOT wont be up by .NET 5. They are doing optimization on blazor wasm. But from what i've read they are doing assembly and field trimming. and runtime optimizations. hope they can get the <1 startup when cached on mobile phones. danroth27 comment

@hoksource

@redradist AOT wont be up by .NET 5. They are doing optimization on blazor wasm. But from what i've read they are doing assembly and field trimming. and runtime optimizations. hope they can get the <1 startup when cached on mobile phones. danroth27 comment

It is sad :(

I have a question. With Blazor AOT are you working on:

  1. compiling C# directly to WebAssembly bytecode format
  2. or are you working on transforming IL compiled in .NET DLLs into WebAssembly bytecode format

The approach 2) would preserve all .NET tools (including our) that rely on standard IL and metadata compiled and also PDB to work. Also 2) would have the additional advantage to have System DLLs also compiled to WebAssembly, maybe with code not executed at runtime pruned (see the Mono.Linker project by @JbEvain).
Thanks

Btw there are a lot of resources out there about Blazor but I didn't find the one with the right granularity to educate myself about Blazor Internals so I wrote it.

2 not 1

Also, I hope AoT process would generate appropriate source maps (from wasm to C#) to make debugging much easier.

I'm hoping to see this support in Q1 2021 for .Net 6 preview releases. This is foundational to support repo's like SkiaSharp running natively in the web browser.

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Was this page helpful?
0 / 5 - 0 ratings