aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md
Following production best practices for serving static assets requires a significant amount of work and technical expertise. Without optimizations like compression, caching, and fingerprints:
Creating performant web apps requires optimizing asset delivery to the browser. Possible optimizations include:
xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A is a new feature that optimizes the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. It's typically a drop-in replacement for UseStaticFiles:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
+app.MapStaticAssets();
-app.UseStaticFiles();
app.MapRazorPages();
app.Run();
MapStaticAssets operates by combining build and publish-time processes to collect information about all the static resources in an app. This information is then utilized by the runtime library to efficiently serve these files to the browser.
MapStaticAssets can replace UseStaticFiles in most situations, however, it's optimized for serving the assets that the app has knowledge of at build and publish time. If the app serves assets from other locations, such as disk or embedded resources, UseStaticFiles should be used.
MapStaticAssets provides the following benefits not found with UseStaticFiles:
gzip during development and gzip + brotli during publish.ETags: The Etags for each resource are the Base64 encoded string of the SHA-256 hash of the content. This ensures that the browser only redownloads a file if its contents have changed.The following table shows the original and compressed sizes of the CSS and JS files in the default Razor Pages template:
File | Original | Compressed | % Reduction -- | -- | -- bootstrap.min.css | 163 | 17.5 | 89.26% jquery.js | 89.6 | 28 | 68.75% bootstrap.min.js | 78.5 | 20 | 74.52% Total | 331.1 | 65.5 | 80.20%
The following table shows the original and compressed sizes using the Fluent UI Blazor components library:
| File | Original | Compressed | % Reduction |
|---|---|---|---|
| fluent.js | 384 | 73 | 80.99% |
| fluent.css | 94 | 11 | 88.30% |
| Total | 478 | 84 | 82.43% |
For a total of 478 KB uncompressed to 84 KB compressed.
The following table shows the original and compressed sizes using the MudBlazor Blazor components library:
| File | Original | Compressed | Reduction |
|---|---|---|---|
| MudBlazor.min.css | 541 | 37.5 | 93.07% |
| MudBlazor.min.js | 47.4 | 9.2 | 80.59% |
| Total | 588.4 | 46.7 | 92.07% |
Optimization happens automatically when using MapStaticAssets. When a library is added or updated, for example with new JavaScript or CSS, the assets are optimized as part of the build. Optimization is especially beneficial to mobile environments that can have a lower bandwidth or an unreliable connections.
For more information on the new file delivery features, see the following resources:
MapStaticAssetsMapStaticAssets has the following advantages over dynamic compression on the server:
Consider the following table comparing MudBlazor compression with IIS dynamic compression and MapStaticAssets:
| IIS gzip | MapStaticAssets | MapStaticAssets reduction |
|---|---|---|
| ≅ 90 | 37.5 | 59% |