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