Skip to content

Optimize file delivery for web apps #52824

Closed
Closed
@javiercn

Description

@javiercn

History

Serving files in ASP.NET Core following production best practices requires a significant amount of work and technical expertise. This usually means that users end up delivering files to the browser in a suboptimal way in their app, even though, for the majority of cases, files are known during the build/publish process and don't change dynamically.This includes optimizations like compression, caching, fingerprinting, and more.

As a result of this, the browser is forced to do additional requests on every page load, more bytes get transferred through the network, and in some cases, even stale versions get served to customers.

Goals

  • Serving a given asset once until it changes or the browser clears its cache.
  • Preclude the browser from using old or stale assets after an app has updated.
  • Preclude the browser from using old asset versions during development.
  • Speed up page load times by delivering assets faster using modern browser features.
  • Minimize the size of assets served to the browser.

Non goals

  • JS minification, CSS minification, and other similar transformations.

Details

We will serve compressed versions for all the assets in your app that benefit from compression, and not just Blazor files. This includes JS, CSS, etc. and any file except for those that are already compressed, like png, jpg, woff, etc.

We will fingerprint all the assets at build time with a hash of the content. This will make the file name unique based on its contents, which will prevent old versions from being reused in lieu of newer versions even if the app has cached the old version.

We will set up caching headers for all the assets that are known at build time. This will make the browser cache the assets for a long time, and only request them again if they change or the browser clears its cache. Fingerprinted assets will be cached using the immutable directive, which will make the browser never request them again until they change, and we will also include a max-age directive to the same effect for browsers that don't support immutable.

We will set up the content-hash as the ETag for all the assets. This will make sure that even if we don't fingerprint a given asset, the browser will be forced to check and download a newer version.

We will provide a map between the assets that aren't fingerprinted and the assets that are that can be used at runtime to find the fingerprinted version of a given asset. This will allow the app to use the fingerprinted version of an asset for files that are automatically generated, like our CSS, and the non-fingerprinted version in the code, like in Razor pages and similar.

This can be use to produce an import map for the app, which will allow the imports in JS files to use the non fingerprinted names, and the browser will automatically use the fingerprinted version. It can also be used to for example, generate link tags in the head of the page to preload the assets without waiting for the browser to discover them.

Metadata

Metadata

Assignees

Labels

Pillar: Technical DebtPriority:0Work that we can't release withoutarea-blazorIncludes: Blazor, Razor ComponentsenhancementThis issue represents an ask for new feature or an enhancement to an existing one

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions