Содержание
В предыдущей части мы познакомились с ещё одной возможностью 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
.