dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.42k stars 10.01k forks source link

EPIC: Support publishing ASP.NET Core API apps with Native AOT (WIP) #45910

Closed DamianEdwards closed 11 months ago

DamianEdwards commented 1 year ago

Overview

.NET 7 introduced support for publishing .NET console projects as native AOT, producing a self-contained, platform-specific executable without any runtime JIT. Native AOT apps start up very quickly and use less memory. The application can be deployed to a machine or container that doesn't have any .NET runtime installed. In .NET 8 we will extend support for native AOT to ASP.NET Core, starting with cloud-focused, API applications built with Minimal APIs that meet expectations regarding published file size, startup time, working set, and throughput performance.

Scope

As stated, the primary focus for .NET 8 will be on enabling native AOT publish of ASP.NET Core API applications using Minimal APIs. "Support native AOT" in this context means ensuring that projects can enable native AOT publish via the <PublishAOT> project property and the resulting development experience leads developers to producing native AOT published applications without build, publish, or runtime warnings and errors. This means that the majority of foundational feature areas of ASP.NET Core and .NET will need to be updated to support native AOT, including:

Additionally, as a secondary goal, we will make progress towards enabling native AOT publish for the following feature areas:

The following feature areas are out of scope for native AOT support for now:

Development experience principles

Native AOT has limitations that mean certain APIs and code patterns in .NET are not supported when publishing native AOT. These include features that rely on runtime JIT, e.g. dynamic code generation and compilation, assembly loading, etc., as well as patterns that result in code being trimmed away by the native AOT compilation process that is needed to execute the application, resulting in runtime failures.

In adding support to ASP.NET Core for native AOT, we must ensure that the development experience is such that developers can reasonably determine how their app will run once published as native AOT. Where current APIs and features are designed in such a way that are incompatible with native AOT, we will utilize tools including source generators, analyzers, and code fixers, to allow existing APIs to work with native AOT or for developers to update their apps to work with native AOT in a reasonable fashion.

Stages

Stage 1

Stage 1 of this effort will be to enable creation of ASP.NET Core API projects using a new project template, enabled for native AOT, that can be built, published, and run without any warnings or errors, and that meets the defined metric targets for executable file size, startup time, working set, and throughput.

Metric Targets

These are primarily Linux-focused as that's the primary deployment target, but size on Windows on macOS will still be tracked and kept in line with these targets as it often contributes to perception during candidate platform investigations.

Stage 2

Stage 2 builds on stage 1 to enable more "real-world" ASP.NET Core API applications to be native AOT published. These applications will use more features typically associated with running API applications in cloud environments including AuthN/Z, data access, OpenTelemetry, etc. The TrimmedTodo API application will serve as the initial example of this kind of application.

Stage 2.a

Feature areas to be made compatible with native AOT in stage 2.a as part of .NET 8:

  1. Configuration & Options inc. binding and validation
  2. Data access via ADO.NET using the Npgsql provider (for PostgreSQL) and, as a secondary priority, Sqlite
  3. Authentication, using the JWT handler, and Authorization using existing ASP.NET Core authorization features
  4. Health Checks, with a primary focus on the in-framework providers and cloud native deployed scenarios, e.g. readiness & health probes
  5. Open Telemetry,

Metric Targets

These are primarily Linux-focused as that's the primary deployment target, but size on Windows on macOS will still be tracked and kept in line with these targets as it often contributes to perception during candidate platform investigations.

Stage 2.b

Feature areas to be made compatible with native AOT in stage 2.b, likely beyond .NET 8. Note that work towards native AOT compatibility for these areas will likely begin in .NET 8, but not be completed:

  1. OpenAPI/Swagger
  2. Validation of minimal API arguments
    • This is a new feature area for .NET 8 that if delivered should be made native AOT friendly
  3. SignalR
  4. MVC Web APIs
sajjadarashhh commented 1 year ago

There is any native aot for blazor wasm?? Native aot for that can be very very hopeful and nice solution for performance issues like size and startup time

DamianEdwards commented 1 year ago

@sajjadarashhh Blazor WebAssembly runs on Mono which has its own native compilation toolchain, separate to native AOT for .NET.

As such, Blazor WebAssembly already supports AOT compilation: https://learn.microsoft.com/aspnet/core/blazor/host-and-deploy/webassembly#ahead-of-time-aot-compilation

sajjadarashhh commented 1 year ago

@DamianEdwards but native aot is not equal to that when we have that dotnet.wasm must be smaller and quicker at startup

DamianEdwards commented 1 year ago

@sajjadarashhh at any rate, this issue is about enabling native AOT for ASP.NET Core apps targeting CoreCLR. Please log a separate issue regarding performance and size of Blazor WebAssembly AOT if you wish to discuss that.

GerardSmit commented 1 year ago
I've tested NativeAOT for ASP.NET Core in .NET 8.0 preview 2 with my "WebForms in .NET" project, which works ๐ŸŽ‰.
Incase you want to read more, you can click here.
_I've put it in a spoiler so this issue doesn't get too big._ It almost worked without any issues. The only issue I had is that the trimmer removed public constructors from controls since they aren't added in the service collection; I'm using `ActivatorUtilities.CreateInstance`. So I've modified the source generator that assembly attributes are being added for every control in the project: ```cs [assembly:WebFormsCore.AssemblyViewAttribute(@"Example.aspx", typeof(Tests.CompiledViews.Example_aspx))] ``` which includes the DynamicallyAccessedMembers-attribute: ```cs public AssemblyViewAttribute(string path, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type); ``` After that, everything works as normally. Now I have WebForms in .NET with NativeAOT (sounds cursed but all in the name of science!) ๐ŸŽ‰. And the size is 15 MB (~6 MB without ASP.NET Core and DI). ![image](https://user-images.githubusercontent.com/2109929/226623983-a7c83190-4f9a-46b4-89b5-c0f92bc55909.png) I'm amazed how it just works. Great job team ๐Ÿ‘ The source-code can be found here: https://github.com/WebFormsCore/WebFormsCore/tree/main/examples/WebFormsCore.Example
JinShil commented 1 year ago

The following feature areas are out of scope for native AOT support for now:

  • MVC views and Razor Pages
  • Blazor Server

That's very unfortunate. I have Blazor Hybrid (WebKitGTK on Linux) applications running on ARM64 that take much too long to start up. If I publish them with NativeAoT, they start up very quickly, but they don't render the UI or they segfault.

mitchdenny commented 1 year ago

That's very unfortunate. I have Blazor Hybrid (WebKitGTK on Linux) applications running on ARM64 that take much too long to start up. If I publish them with NativeAoT, they start up very quickly, but they don't render the UI or they segfault.

Thanks for the feedback @JinShil - getting ASP.NET running on the native AOT deployment model is a process. As we achieve each milestone, we can re-evaluate features that are currently out of scope.

hez2010 commented 1 year ago

Would like to see NativeAOT support for razor component too.

dameng324 commented 1 year ago

The following feature areas are out of scope for native AOT support for now:

MVC views and Razor Pages Blazor Server

Is there any plan to support Blazor Server with NativeAOT ? maybe .net9 ?

DamianEdwards commented 1 year ago

Is there any plan to support Blazor Server with NativeAOT ? maybe .net9 ?

Not concrete yet, but it's certainly in the list of areas to consider.

eerhardt commented 11 months ago

@DamianEdwards - can this Epic be closed now that 8.0 has shipped?

SquareHatLtd commented 11 months ago

Will AOT ASP.NET Core ever support Https.

Our company (as many financial sector companies have) is a policy that all data has to be encrypted both in flight and at rest. It would be a shame to miss out on all the AOT goodness simply because HTTPS is not supported.

Thanks Stephen

martincostello commented 11 months ago

My understanding is that is supported in .NET 8: Reduced app size with configurable HTTPS support

DamianEdwards commented 11 months ago

@SquareHatLtd HTTPS is supported, but if using WebApplication.CreateSlimBuilder you need to add HTTPS support for Kestrel back in as it's not included in the defaults, e.g.:

var builder = WebApplication.CreateSlimBuilder(args);

builder.WebHost.UseKestrelHttpsConfiguration();
w-as commented 11 months ago

The team has done some truly remarkable work on this feature, thank you! Just checking whether there is any update on plans for Stage 2.b, particularly w.r.t OpenAPI/Swagger. Thanks again!

eerhardt commented 11 months ago

@w-as - do you need your OpenAPI/Swagger endpoint in production? One approach we took in the TodosApi benchmark app was to make it a development-only time feature. See

NotTsunami commented 9 months ago

@w-as - do you need your OpenAPI/Swagger endpoint in production? One approach we took in the TodosApi benchmark app was to make it a development-only time feature. See

Chiming in here. In some of our apps, we make it development-only as well. But we provide a lot of utility via our OpenAPI/Swagger endpoints and we actually have a customer that prefers we ship with Swagger in prod. There are absolutely alternatives to this, but it would be nice to see support at some point for OpenAPI in Native AOT (although it is not at all necessary, would be extra brownie points). The bigger blocker for us in moving some apps to Native AOT is lack of SignalR support. Hoping to see this roadmapped soon!

w-as commented 9 months ago

@w-as - do you need your OpenAPI/Swagger endpoint in production? One approach we took in the TodosApi benchmark app was to make it a development-only time feature. See

I'm sorry I missed your response back in November, thank you for the suggestion of dev-time only. We do currently publish the OpenAPI/Swagger endpoints in production yes, however it may be possible to create clients based on dev-time specs so will investigate that, thank you.

Hylaean commented 7 months ago

Great job there! Is Stage 2.b targeted for .NET 9? SignalR at least?

eerhardt commented 4 months ago

Is Stage 2.b targeted for .NET 9? SignalR at least?

Check out the update to this issue: https://github.com/dotnet/aspnetcore/issues/41704#issuecomment-2190200815. My plan is to get SignalR support with the JSON protocol in for .NET 9 preview 7.