Содержание
Любое современное более менее серьезное веб-приложение помимо непосредственно данных может отсылать клиенты в ответе различные ресурсы — файлы со скриптами, CSS, картинки и т.д. Все эти элементы нагружают ответ лишними байтами/килобайтами, а, иногда и мегабайтами данных, что может негативно сказаться на производительности приложения. Для повышения производительности нашего приложения, помимо кэширования объектов и статических файлов, мы можем также использовать сжатие ответа сервера, что позволяет снизить объем передаваемых данных по Сети. Следует сразу отметить, что рассмотренные ниже примеры будут показывать хороший результат только для серверов Kestrel и Http.sys так как здесь по умолчанию отключено сжатие ответа. На IIS вы, скорее всего, ничего не заметите, так как здесь уже включено сжатие по умолчанию.
Тестовый пример
Для примера того как работает сжатие ответов в ASP.NET Core создадим небольшое приложение, которое будет работать только со статическими файлами. Код файла Program.cs:
namespace AspResponseCompression { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run(); } } }
Создадим в корневой папке проекта папку wwwroot и добавим в неё два файла:
Файл style.css
h1 { font-family: 'Arial', 'Verdana', sans-serif; } p { font-family: 'Arial'; font-size: 21px; }
Файл index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Static File</title> <link rel="stylesheet" href="style.css" /> </head> <body> <h1>Аркадий Стругацкий, Борис Стругацкий. Трудно быть богом</h1> <p>Психологически почти все они были рабами — рабами веры, рабами себе подобных, рабами страстишек, рабами корыстолюбия. И если волею судеб кто-нибудь из них рождался или становился господином, он не знал, что делать со своей свободой. Он снова торопился стать рабом — рабом богатства, противоестественных излишеств, рабом распутных друзей, рабом своих рабов.</p> <p>Зло неистребимо. Никакой человек не способен уменьшить его количество в мире. Он может несколько улучшить свою собственную судьбу, но всегда за счет ухудшения судьбы других. И всегда будут короли, более или менее жестокие, бароны, более или менее дикие, и всегда будет невежественный народ, питающий восхищение к своим угнетателям и ненависть к своему освободителю. И все потому, что раб гораздо лучше понимает своего господина, пусть даже самого жестокого, чем своего освободителя, ибо каждый раб отлично представляет себя на месте господина, но мало кто представляет себя на месте бескорыстного освободителя. Таковы люди, дон Румата, и таков наш мир.</p> <p>Останемся гуманными, всех простим и будем спокойны, как боги. Пусть они режут и оскверняют, мы будем спокойны, как боги. Богам спешить некуда, у них впереди вечность.</p> <p>Кстати, благородные доны, чей это вертолет позади избы?</p> <p>Нужно, наконец, твердо понять, что ни ты, ни я, никто из нас реально ощутимых плодов своей работы не увидим. Мы не физики, мы историки. У нас единица времени не секунда, а век, и дела наши – это даже не посев, мы только готовим почву для посева. А то прибывают порой с Земли… энтузиасты, черт бы их побрал… Спринтеры с коротким дыханием…</p> <p>Выдумают, надо же!.. Мир круглый! По мне хоть квадратный, а умов не мути!..», «От грамоты, от грамоты все идет, братья! Не в деньгах, мол, счастье, мужик, мол, тоже человек, дальше – больше, оскорбительные стишки, а там и бунт…», «Всех их на кол, братья!.. Я бы делал что? Я бы прямо спрашивал: грамотный? На кол тебя! Стишки пишешь? На кол! Таблицы знаешь? На кол, слишком много знаешь!»</p> </body> </html>
Запустим приложение и посмотрим на размер получаемых данных:
Наши два файла имеют объем порядка 4,5 kB и отправляются, на данный момент, в несжатом виде. Теперь включим сжатие ответа в ASP.NET Core и посмотрим на результат.
Включение сжатия ответов в ASP.NET Core
Для включения сжатия ответов в ASP.NET Core нам необходимо добавить сервисы сжатия, используя для этого метод расширения AddResponseCompression()
, а также подключить middleware компонент ResponseCompressionMiddleware
для сжатия ответов, используя метод расширения UseResponseCompression()
. Допишем наш тестовый пример следующим образом:
namespace AspResponseCompression { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // добавляем сервисы сжатия builder.Services.AddResponseCompression(); var app = builder.Build(); // подключаем сжатие app.UseResponseCompression(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run(); } } }
Теперь снова запустим наше приложение и посмотрим на результат:
Как можно видеть, теперь объем передаваемых данных в ответе составил всего чуть более 2 kB, что указывает на то, что сжатие работает.
Заголовки Content-Encoding и Accept-Encoding
На уровне протокола HTTP сжатие ответов заключается в том, что сервер отправляет клиенту заголовок Content-Encoding
в котором указывается способ сжатия контента. В этом заголовке могут использоваться следующие значения:
identity
— сжатие не используется, значение по умолчанию для кодирования контента.gzip
— формат GNU zip использует алгоритм deflate для сжатия.compress
— программный метод «сжатия» в UNIX, устарел и заменен на gzip или deflate.deflate
— сжатие на основе алгоритма deflate.br
— сжатие на основе алгоритма Brotli
В нашем примере использовался последний алгоритм сжатия — Brotli, о чем говорит заголовок сервера:
Что касается клиента, то, чтобы сервер отправлял сжатый ответ, при отправке запроса в заголовки включается заголовок Accept-Encoding
с перечислением поддерживаемых методов сжатия, например:
Accept-Encoding: gzip, deflate, br
Итого
Сжатие ответов, наряду с кэшированием, позволяет повысить производительность приложения ASP.NET Core. Для включения сжатия необходимо подключить сервисы сжатия и добавить в конвейер обработки запросов middleware для сжатия ответа. По умолчанию, в ASP.NET Core (при использовании сервера Kestrel) используется алгоритм сжатия Brotli. В следующей части разберемся с настройками сжатия.