Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AoT compilation #5466

Open
danroth27 opened this issue Jan 25, 2018 · 36 comments
Open

AoT compilation #5466

danroth27 opened this issue Jan 25, 2018 · 36 comments

Comments

@danroth27
Copy link
Member

@danroth27 danroth27 commented Jan 25, 2018

Compile everything to WebAssembly

@danroth27 danroth27 self-assigned this Mar 23, 2018
@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Mar 23, 2018

Follow up on status of mono-wasm

@danieldegtyarev

This comment has been minimized.

Copy link

@danieldegtyarev danieldegtyarev commented Apr 24, 2018

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

@danieldegtyarev

This comment has been minimized.

Copy link

@danieldegtyarev danieldegtyarev commented Apr 27, 2018

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

.NET 300 ms
WASM: 13155 ms

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Apr 27, 2018

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.

@stefan-schweiger

This comment has been minimized.

Copy link

@stefan-schweiger stefan-schweiger commented May 17, 2018

@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.

@csnewman

This comment has been minimized.

Copy link

@csnewman csnewman commented May 17, 2018

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.

@TheFanatr

This comment has been minimized.

Copy link

@TheFanatr TheFanatr commented Jun 26, 2018

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?

@stefan-schweiger

This comment has been minimized.

Copy link

@stefan-schweiger stefan-schweiger commented Jun 26, 2018

@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.

@stavroskasidis

This comment has been minimized.

Copy link

@stavroskasidis stavroskasidis commented Sep 30, 2018

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

dotnet/corert#4659 (comment)

@aspnet-hello aspnet-hello transferred this issue from aspnet/Blazor Dec 17, 2018
@aspnet-hello aspnet-hello assigned danroth27 and unassigned danroth27 Dec 17, 2018
@aspnet-hello aspnet-hello added this to the Backlog milestone Dec 17, 2018
@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented Apr 20, 2019

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.

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Apr 22, 2019

@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.

@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented May 26, 2019

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?

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented May 26, 2019

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

@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented Jun 5, 2019

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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Sep 11, 2019

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.

@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented Sep 12, 2019

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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Sep 12, 2019

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.

@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented Sep 13, 2019

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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Sep 13, 2019

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.

@keithwill

This comment has been minimized.

Copy link

@keithwill keithwill commented Sep 30, 2019

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

@rynowak rynowak added the blazor-wasm label Sep 30, 2019
@rynowak

This comment has been minimized.

Copy link
Member

@rynowak rynowak commented Sep 30, 2019

Your wish is my command 😆

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Sep 30, 2019

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.

@legistek legistek mentioned this issue Sep 30, 2019
11 of 15 tasks complete
@Andrzej-W

This comment has been minimized.

Copy link

@Andrzej-W Andrzej-W commented Oct 1, 2019

I have posted this question here mono/mono#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!!!

@freefrom-co-jp

This comment has been minimized.

Copy link

@freefrom-co-jp freefrom-co-jp commented Oct 1, 2019

@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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 1, 2019

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).

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Oct 1, 2019

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

@Andrzej-W

This comment has been minimized.

Copy link

@Andrzej-W Andrzej-W commented Oct 1, 2019

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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 1, 2019

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

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Oct 1, 2019

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

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 1, 2019

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.

@danroth27

This comment has been minimized.

Copy link
Member Author

@danroth27 danroth27 commented Oct 2, 2019

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

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 29, 2019

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 (mono/mono#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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 31, 2019

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?

@Feroks

This comment has been minimized.

Copy link

@Feroks Feroks commented Oct 31, 2019

@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.

@legistek

This comment has been minimized.

Copy link

@legistek legistek commented Oct 31, 2019

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.

@honkmother

This comment has been minimized.

Copy link

@honkmother honkmother commented Nov 2, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.