The size of a simple .NET 8 application reaching 30 MB, especially when published as a self-contained application, can be attributed to several factors, primarily stemming from the nature of self-contained deployments and how .NET handles dependencies and runtime components. Here’s an explanation of why this occurs and some steps you can take to possibly reduce the size:
When you choose a self-contained deployment (SCD), the application is published with all the necessary .NET runtime files and libraries required to run the application. This includes the entire .NET runtime and any framework libraries that your application uses. This is beneficial for running the application on systems without requiring .NET to be installed, but it significantly increases the file size.
.NET applications rely on a substantial number of system libraries and runtime components that must be included in a self-contained package. This ensures that the application can run independently of the libraries installed on the target system. These components include base class libraries, runtime bindings, JIT compilers, garbage collection, and more.
.NET provides options to trim out unused libraries from the output during publishing. However, trimming can only reduce the size to a certain extent. It works by analyzing the application’s IL code statically to determine which framework APIs are being called, which can lead to conservative trimming decisions to avoid breaking the application at runtime.
ReadyToRun (R2R) is a feature that can increase the output size but improve startup performance. R2R compiles the code ahead of time to native code, which eliminates the need for JIT compilation at runtime but increases the size of the deployed application because it includes compiled native binaries.
a. Enable More Aggressive Trimming:
Ensure that the .csproj file is configured to enable aggressive trimming. You can specify this in your project file:
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>link</TrimMode>
b. Use IL Linker Properties:
Configure the IL linker to be more aggressive. This might involve some trial and error to ensure that the application still functions correctly after additional components are trimmed.
<TrimmerDefaultAction>link</TrimmerDefaultAction>
c. Disable ReadyToRun:
If you have enabled ReadyToRun, consider disabling it if startup performance is not a critical issue. This can reduce the output size:
<PublishReadyToRun>false</PublishReadyToRun>
d. Review Dependencies:
Analyze and review your project’s dependencies. Remove any unnecessary NuGet packages or libraries that are not essential to your application.
e. Consider Runtime Features:
Disable any runtime features that are not necessary for your application. Each additional feature or library included can increase the size.
<InvariantGlobalization>true</InvariantGlobalization> <!-- Example: Only if applicable -->
f. Consider Targeting a Single Platform:
If your application targets multiple platforms (e.g., win-x64, linux-x64), consider targeting only the platforms you need. Each platform could require different runtime components, increasing the overall size.
A simple .NET 8 application might end up being 30 MB in size due to the inclusion of the complete runtime and libraries needed for a self-contained deployment. By fine-tuning the trimming settings, managing dependencies, and adjusting the deployment strategy, you can potentially reduce the size of your application.