Internet traffic can be compressed to save network bandwidth usage. While images and web fonts are already compressed, text files are stored on the server in human-readable form. HTTP.sys server and Kestrel currently don't have built-in compression support. By default, only static files are compressed with gzip. What if you want to compress more?
Reasons
There are several reasons why you might want to change the compression configuration:
- Support Brotli compression format
- Compress over TLS
- Compress dynamically generated content
Brotli
Two engineers at Google designed the Brotli compression format. In comparison to gzip, Brotli is around 20% more performant in compression and around 20 times faster in decompression. It is used in the WOFF2 format. Brotli uses Huffman coding and a variant of the LZ77 algorithm. All major browsers support Brotli (Firefox since January 2016, Chrome since April 2016, Opera since June 2016, Edge since April 2017, and Safari since October 2017).
Compress in TLS
Compression in TLS is compromised due to the BREACH attack. However, if your cookies follow the same-site policy, your site is protected against CSRF and BREACH attacks.
Compress dynamic content
Unlike static files, dynamic content cannot be cached, thus every response must be compressed individually. It gives you more efficient use of bandwidth but also higher CPU load.
Implementation
Allowing compression in an ASP.NET Core 2 web app is very easy.
Step 1 – Use response compression
In the Startup.cs file, call the UseResponseCompression
method:
public class Startup {
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.UseResponseCompression();
}
}
Step 2 – enable gzip compression
In the Startup.cs file call the Configure
method:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.Configure<GzipCompressionProviderOptions>(options => {
options.Level = CompressionLevel.Fastest;
});
}
}
Step 3 – create a Brotli compression provider
First, you must install the BrotliSharpLib NuGet package because Brotli isn’t currently supported in .NET Core 2.0.0.
Second, add a new class that provides Brotli compression.
public class BrotliCompressionProvider : ICompressionProvider {
public string EncodingName => "br";
public bool SupportsFlush => true;
public Stream CreateStream(Stream outputStream) => new BrotliStream(outputStream, CompressionMode.Compress);
}
Step 4 – register a Brotli compression provider
In the Startup.cs file call the AddResponseCompression
method:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options => {
options.Providers.Add<BrotliCompressionProvider>();
});
}
}
Step 5 – enable compression in TLS connection
In the Startup.cs file, set the EnableForHttps
property in the AddResponseCompression
method call:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddResponseCompression(options => {
options.Providers.Add<BrotliCompressionProvider>();
options.EnableForHttps = true;
});
}
}
Step 6 – Declare additional MIME types for compression
By default, only the following MIME types are compressed by ASP.NET Core 2:
- text/plain
- text/css
- application/javascript
- text/html
- application/xml
- text/xml
- application/json
- text/json
Your web application may serve more MIME types that can be compressed, for example:
- application/xhtml+xml
- application/atom+xml
- image/svg+xml
In the Startup.cs file, set the MimeTypes
property in the AddResponseCompression
method call:
public class Startup {
public void ConfigureServices(IServiceCollection services) {
options.Providers.Add<BrotliCompressionProvider>();
options.EnableForHttps = true;
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] {
"application/xhtml+xml",
"application/atom+xml",
"image/svg+xml",
});
}
}
Step 7 – Test it
F12 Dev Tools currently do not show the content-encoding
response header. This is a known bug that has taken over a year to fix. You must run an alternative browser to test whether your server responds with the content-encoding: br
HTTP header.
Further thoughts
- Edge, Chrome, and Firefox declare Brotli support in TLS connections only. There is a practical reason for this. When the Chrome and Firefox teams tried to implement bzip2 and SDCH compression, they found that some proxy servers spoiled HTTP content.
- Brotli Compressed Data Format is standardized by IETF as RFC 7932.
- Microsoft has already been working on Brotli support in ASP.NET Core, but the package is still not ready for production yet.
- ASP.NET Core 2 currently doesn’t support disabling dynamic compression when the CPU reaches high load, unlike IIS.
- Content compression is a much more efficient way of reducing response size than minifying CSS or JavaScript files.