Dajbych.net


How to Enable Response Compression in ASP.NET Core 2 With gzip and Brotli Encoding

, 4 minutes to read

net2015 logo

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:

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:

Your web application may serve more MIME types that can be compressed, for example:

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