Сжатие ответов в ASP.NET Core. Настройки сжатия

В предыдущей части мы познакомились с ещё одной возможностью ASP.NET Core — сжатием ответов. В этой части мы более подробно разберемся с тем, какие настройки мы можем использовать в сервисах сжатия ответов и как эти настройки могут повлиять на производительность приложения ASP.NET Core.

Класс ResponseCompressionOptions

Для того, чтобы настроить сервисы сжатия ответов, в метод AddResponseCompression() необходимо передать делегат вида:

Action<ResponseCompressionOptions> configureOptions

Объект типа ResponseCompressionOptions содержит следующие свойства:

Свойство Описание
IEnumerable<string> MimeTypes
MIME-типы данных, которые будут сжиматься
public IEnumerable<string> ExcludedMimeTypes
MIME-типы данных, которые необходимо исключить из сжатия
public bool EnableForHttps
Указывает, следует ли сжимать ответы при использовании HTTPS. По умолчанию установлено значение false так как включение сжатия HTTPS-запросов может привести к проблемам с безопасностью.
public CompressionProviderCollection Providers
Коллекция провайдеров, используемых для сжатия ответа. Приоритет провайдера определяется порядком его добавления в коллекцию.

Попробуем настроить наше приложение следующим образом:

// добавляем сервисы сжатия
builder.Services.AddResponseCompression(options => {
    options.EnableForHttps = true;
    options.ExcludedMimeTypes = new[] { "text/html" };
});

В данном случае, мы указываем, что не требуется сжимать данные с MIME-типом «text/html», что, в нашем случае, приводит к тому, что ответ не будет сжиматься. Аналогичным образом, мы можем явно указать MIME-типы данных, которые необходимо сжимать при отправке ответа, например,

builder.Services.AddResponseCompression(options => {
     options.EnableForHttps = true;
     options.ExcludedMimeTypes = new[] { "text/html" };
     options.MimeTypes = new[] { "application/font-woff2", "application/font-woff", "application/font", "font/opentype" };
 });

Следует отметить, что MIME-типы данных, сжимаемых по умолчанию содержатся в массиве ResponseCompressionDefaults.MimeTypes:

  • «text/plain»,
  • «text/css»,
  • «application/javascript»,
  • «text/javascript»,
  • «text/html»,
  • «application/xml»,
  • «text/xml»,
  • «application/json»,
  • «text/json»,
  • «application/wasm»,

поэтому, эти MIME-типы можно не добавлять в список MimeTypes объекта ResponseCompressionOptions .

Отдельное внимание стоит уделить свойству CompressionProviderCollection.

Провайдеры компрессии (сжатия)

На данный момент, в ASP.NET Core имеется два готовых провайдера сжатия — это BrotliCompressionProvider (алгоритм Brotli, используется по умолчанию) и GzipCompressionProvider (сжатие gzip). Чтобы определить несколько провайдеров сжатия, необходимо добавить их в настройки сервиса (свойство CompressionProviderCollection) в порядке их приоритетности. Например, по умолчанию ASP.NET Core использует сжатие с использованием Brotli. Если мы хотим, чтобы данные в первую очередь сжимались gzip, то можем задать такие настройки сервиса сжатия:

builder.Services.AddResponseCompression(options => {
    options.EnableForHttps = true;
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes;
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<BrotliCompressionProvider>();
});

В этом случае сервер будет действовать следующим образом: если клиент поддерживает сжатие gzip, то ответ будет сжат с использованием этого алгоритма и отправлен клиенту. Если gzip клиентов не поддерживается, но поддерживается Brotli, то ответ будет сжат и отправлен с заголовком Content-Encoding: br

Для провайдера сжатия можно настроить уровень сжатия контента. Уровень сжатия задается с помощью одного из значений перечисления CompressionLevel следующим образом

// добавляем сервисы сжатия
builder.Services.AddResponseCompression(options => {
    options.EnableForHttps = true;
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes;
    options.Providers.Add(new GzipCompressionProvider(new GzipCompressionProviderOptions() 
    { 
        Level = System.IO.Compression.CompressionLevel.SmallestSize
    }));
    options.Providers.Add(new BrotliCompressionProvider(new BrotliCompressionProviderOptions() 
    { 
        Level= System.IO.Compression.CompressionLevel.Optimal
    }));
});

Здесь мы указали для gzip уровень сжатия при котором будет достигнут наименьший размер, а для Brotli — оптимальный уровень сжатия как по размеру, так и по скорости сжатия. Следует отметить, что по умолчанию, для всех провайдеров сжатия используется значение CompressionLevel.Fastest — наиболее быстрое сжатие в ущерб размеру выходных данных.

В предыдущей части мы также рассмотрели возможные варианты значений заголовка Content-Encoding. В числе прочих значений, в нем также может использоваться значение deflate. Но такого провайдера в ASP.NET Core нет, поэтому, в случае необходимости, нам необходимо будет создать свой провайдер сжатия.

Пользовательские провайдеры сжатия

Класс, определяющий пользовательский провайдер сжатия должен реализовывать интерфейс ICompressionProvider, который содержит следующие свойства и методы:

Свойство
string EncodingName { get; }
значение, которое используется в заголовках Accept-Encoding и Content-Encoding
Свойство
bool SupportsFlush { get; }
Указывает, поддерживает ли данный поставщик методы Flush и FlushAsync. Если значение равно false, то в некоторых сценариях сжатие может быть отключено.
Метод
Stream CreateStream(Stream outputStream);
Возвращает поток ответа после сжатия

 

Напишем свой провайдер сжатия ответа с использованием deflate:

public class DeflateCompressionProvider : ICompressionProvider
{
    public string EncodingName { get; } = "deflate";

    public bool SupportsFlush { get; } = true;

    public Stream CreateStream(Stream outputStream)
    {
        return new DeflateStream(outputStream, CompressionLevel.SmallestSize);
    }
}

Используем этот провайдер в своем приложении:

// добавляем сервисы сжатия
builder.Services.AddResponseCompression(options => {
    options.EnableForHttps = true;
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes;
    
    options.Providers.Add(new DeflateCompressionProvider());//свой провайдер сжатия
    
    options.Providers.Add(new GzipCompressionProvider(new GzipCompressionProviderOptions() 
     { 
         Level = System.IO.Compression.CompressionLevel.SmallestSize
     }));
    options.Providers.Add(new BrotliCompressionProvider(new BrotliCompressionProviderOptions() 
    { 
        Level= System.IO.Compression.CompressionLevel.SmallestSize
    }));
});

Если клиент по какой-либо причине не будет поддерживать сжатие deflate, то для сжатия ответа будет выбран один из стандартных провайдеров.

Итого

При использовании сжатия ответов в ASP.NET Core мы можем указывать MIME-типы данных, которые должны или НЕ должны подвергаться сжатию, а также указывать несколько провайдеров сжатия, приоритет которых будет определяться из положением в коллекции Providers настроек сервиса. Для создания собственного провайдера сжатия его класс должен реализовывать интерфейс ICompressionProvider.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии