Optimize Garbage Collection (GC)
Tune the garbage collection settings for your application based on its memory usage and workload.
For server workloads, enable server GC for better performance with multi-threaded applications
<PropertyGroup>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>
GCSettings.LatencyMode: For latency-sensitive applications (e.g., web APIs), you can configure the latency mode to minimize the impact of garbage collection during startup.
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
Optimize Razor Pages and Views (For ASP.NET Core)
If you’re building a web application using Razor Pages or Views, the compilation of Razor files can introduce startup delays.
Precompile Razor Views: Precompile your Razor views to avoid runtime compilation during startup.
Add this to your .csproj file:
<PropertyGroup>
<RazorCompileOnPublish>true</RazorCompileOnPublish>
</PropertyGroup>
This ensures that views are compiled at build or publish time, reducing startup time.
Reduce the Size of the Application Binary
The larger your application, the more time it takes to load the assemblies.
Trim Unused Libraries: Use ILLinker (available in .NET Core) to trim unused code, removing unnecessary parts of libraries that aren’t used by your application. Add this to your .csproj:
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
This feature analyzes dependencies and removes unused parts, reducing the application size and improving startup time.
Single-File Publish: In .NET Core 3.0+ and .NET 5/6/7/8, you can publish your application as a single-file executable to avoid the overhead of loading multiple assemblies at startup.
Add this to your .csproj:
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Use Ahead-of-Time (AOT) Compilation
.NET 7 and .NET 8 offer Native AOT (Ahead-of-Time Compilation), which compiles .NET applications directly into machine code, eliminating the need for JIT (Just-In-Time) compilation during startup.
Native AOT: For applications where startup performance is critical, you can compile your .NET code ahead of time into native code.
Add this to your .csproj:
<PropertyGroup>
<PublishAot>true</PublishAot>
</PropertyGroup>
This feature greatly improves startup performance by reducing the time spent on JIT compilation.
Use HTTP/2 and Enable Response Compression
If your .NET Core application serves HTTP traffic, enabling HTTP/2 and response compression can improve the startup performance from the user’s perspective.
HTTP/2: HTTP/2 reduces the number of connections and allows multiplexing of requests. Enable it in Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 5000, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});
});
Response Compression: Use response compression to decrease the size of payloads sent to the client, reducing startup time over the network.
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
}
Use HTTP/3
HTTP/3 reduces latency and enhances startup performance for web applications with its improved connection model over HTTP/2. .NET 6 and later versions support HTTP/3.
Enable HTTP/3 by configuring Kestrel:
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
HTTP/3 offers faster connection establishment, which improves the perceived startup performance from the client’s perspective.
Use Ready-to-Run (R2R) Compilation
Ready-to-Run (R2R) is a feature that pre-compiles your .NET assemblies into native code at build time, reducing the time spent on JIT compilation.
Enable R2R in your .csproj file:
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
This can significantly improve startup times, especially for large applications, by eliminating the need for JIT compilation at runtime.