Русские документы
Ежедневные компьютерные новости RSS rusdoc.ru  Найти :
Новости
Последние поступления
Книжный магазин
  Hardware:
Видеоустройства
Системные платы
Процессоры
Мобильные устройства
Аудиосистема
Охлаждение системы
Накопители информации
КПК и ноутбуки
Телефоны и связь
Периферия
Система
Сети
Разные устройства
 
  Programming:
Web-разработка
Языки программирования
Технологии и теория
Разработка игр
Программная инженерия
 
  Software:
Операционные системы
Windows 7
Базы данных
Обзоры программ
Графика и дизайн
   
  Life:
Компьютерная жизнь
Разные материалы
   
Партнеры
Публикация
Правовая информация
Реклама на сайте
Обратная связь
Экспорт в RSS Экспорт в RSS2.0
    Читать в Яндекс.Ленте



asp.net: gzip, несколько вариантов включения

Раздел: Programming / ASP.NET @ 28.05.2008 | Ключевые слова: gzip-сжатия сжатие gzip asp.net версия для печати

Автор: XaocCPS
Источник: habrahabr

Сжатие web-содержимого посредством gzip (GNU zip) – это довольно старая технология. Суть ее сводится к тому, что web-содержимое перед отправкой пользователю сжимается по известному всем алгоритму zip. Сама спецификация gzip описана в RFC1952, версия 4.2 которой датируется маем 1996 года. На сегодняшний день все популярные браузеры и веб-серверы поддерживают сжатие web-содержимого посредством gzip. В этой статье я постараюсь рассказать о нескольких способах включения в проекты asp.net поддержки gzip-сжатия.

Включение HTTP-compression на сервере IIS


Первый способ самый простой. Вы просто нажимаете пару кнопок в настройках IIS, и вот уже web-сервер обеспечивает вам автоматическое сжатие для клиентов, которые gzip поддерживают.



Для тех, кто не знает, как в IIS включить сжатие, рассказываю: необходимо в диспетчере служб IIS зайти в свойства элемента «Веб узлы» и перейти во вкладку «Служба».



Данный способ самый простой, но вместе с тем не самый гибкий.
Плюсы такого включения сжатия:
• простота;
• поддержка сжатия IIS статических файлов;
• поддержка кэширования сжатых файлов;
• не требует написания кода.

Минусы включения поддержки сжатия на сервере IIS:
• сервер решает: вы не будете знать что, когда и как сжимается;
• глобальное включение: сжатие включается для всей службы разом и будет влиять на все узлы или виртуальные каталоги вашего сервера (по крайне мере, через gui отключить сжатие у конкретного узла нельзя);
• проблемы: лично я столкнулся с проблемой, когда один из пользователей пожаловался на то, что у него стала отображаться пустая главная страница как раз после включения сжатия через IIS, после выключения все вернулось в норму. Данный момент скорее из разряда частных и к общему случаю не подходит, но я привел его, как пример того, почему глобальное включение сжатие в IIS может вас не устроить.

Application_BeginRequest


Суть этого метода, описанного в интеренете во многих источниках, например, тут

http://www.stardeveloper.com/articles/di…

состоит в том, что вы, используя, появившиеся в .net framework 2.0 классы System.IO.Compression.GZipStream и System.IO.Compression.DeflateStream определяете свой собственный фильтр содержимого http-запроса, который перед отправкой клиенту, сжимает данные посредством методов GZipStream. Особенность этого метода в том, что все действия по сжатию содержимого производятся в global.asax в методе Application_BeginRequest, который вызывается перед запросом пользователя. Тем самым можно создать фильтр на любой запрос пользователя для отправки всего содержимого Response в сжатом виде. Вот как этот метод выглядит в исходном виде (взято с сайта указанного выше):

<%@ Application Language="C#" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.IO.Compression" %>

<script runat="server">
void Application_BeginRequest(object sender, EventArgs e)
{
  HttpApplication app = (HttpApplication)sender;
  string acceptEncoding = app.Request.Headers["Accept-Encoding"];
  Stream prevUncompressedStream = app.Response.Filter;

  if (acceptEncoding == null || acceptEncoding.Length == 0)
    return;

  acceptEncoding = acceptEncoding.ToLower();

  if (acceptEncoding.Contains("gzip"))
  {
    // gzip
    app.Response.Filter = new GZipStream(prevUncompressedStream,
      CompressionMode.Compress);
    app.Response.AppendHeader("Content-Encoding",
      "gzip");
  }
  else if (acceptEncoding.Contains("deflate"))
  {
    // defalte
    app.Response.Filter = new DeflateStream(prevUncompressedStream,
      CompressionMode.Compress);
    app.Response.AppendHeader("Content-Encoding",
      "deflate");
  }
}
</script>


* This source code was highlighted with Source Code Highlighter.



Основные плюсы данного метода:
• расположение в global.asax позволяет решить проблему централизованно, разом разрешив сжатие для всего потока данных в контексте одного web-приложения asp.net;
• сжимается практически весь контент;
• немного переделав этот код, можно гибко фильтровать содержимое для сжатия.
Минусы данного метода:
• способ определяет правило для всего приложения, нет возможности отключить сжатие для ряда страниц;
• данный метод некорректно работает с ajax.net, что вообще не позволяет использовать его в ajax-ориентированном приложении;
• по сравнению с первым методом через IIS, здесь приходится писать код и сопровождать его.

Надо заметить, что проблема с ajax.net возможно имеет решение, но мне на момент написания статьи такое решение не известно. Я буду благодарен, если кто-нибудь опишет реализацию данного способа включения gzip в ajax.net проектах.

GZipEncodePage


Отличный специалист Rick Strahl на своем блоге

http://west-wind.com/WebLog/default.aspx

приводит еще один, альтернативный способ сжатия web-страниц посредство gzip. Рассмотрим пару функций которые он написал, а я сделал статическими:

    public static bool IsGZipSupported()
    {
      string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];
      if (!string.IsNullOrEmpty(AcceptEncoding) &&
         (AcceptEncoding.Contains("gzip") || AcceptEncoding.Contains("deflate")))
        return true;
      return false;
    }

    public static void GZipEncodePage()
    {
      if (IsGZipSupported())
      {
        HttpResponse Response = HttpContext.Current.Response;

        string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];
        if (AcceptEncoding.Contains("gzip"))
        {
          Response.Filter = new System.IO.Compression.GZipStream(Response.Filter,
                       System.IO.Compression.CompressionMode.Compress);
          Response.AppendHeader("Content-Encoding", "gzip");
        }
        else
        {
          Response.Filter = new System.IO.Compression.DeflateStream(Response.Filter,
                       System.IO.Compression.CompressionMode.Compress);
          Response.AppendHeader("Content-Encoding", "deflate");
        }
      }
    }


* This source code was highlighted with Source Code Highlighter.



Первый метод просто проверяет поддержку клиентом технологии сжатия, а вот второй очевидно практически равносилен методу из примера о Application_BeginRequest, только в данном случае вынесен в отдельную функцию. Что это дает? Ну, во-первых, рассмотрим использование:

protected void Page_Load(object sender, EventArgs e)
{
  HtmlUtil.GZipEncodePage();
}


* This source code was highlighted with Source Code Highlighter.



Очевидно, что данный метод работает на уровне пользовательских страниц. Работает только с телом страницы и не обрабатывает js,css и любые другие файлы.

Плюсы этого подхода:
• работает на уровне одной страницы, позволяет включать сжатие только на тех страницах, где это требуется;
• не сжимает ничего кроме тела страницы, тем самым не конфликтуя с ajax.net.
Минусы:
• нет возможности разом включить сжатие везде на сайте;
• не сжимает js, css и другие ресурсы;
• необходимо писать код и поддерживать его.

Очень важно, при использовании этого метода вызывать его до любой первой записи в Response.

Послесловие


Лично я остановился на третьем варианте. Во-первых, часть моего проекта написана на ajax.net и второй вариант у меня не заработал. Во-вторых, я столкнулся с проблемой при включении централизованного сжатия на уровне IIS, следовательно, и первый вариант мне не подошел. В-третьих, третий подход лично мне кажется элегантным и гибким. Для сжатия js и css можно поискать и другие способы, а сжатие одних только aspx уже дает заметный выигрыш в размере трафика.

Приведу некоторые данные:
• по моим измерениям размер данных страниц передаваемых клиенту при сжатии через gzip уменьшился в среднем в шесть раз;
• размер ajax-ответов клиенту уменьшился в среднем в десять раз;
• увеличение нагрузки на процессор на сервере не берусь оценить, но в интернете ее оценивают как ~5%, что для себя считаю вполне допустимым.

Для себя делаю вывод, что сжатие одних только страниц позволяет значительно уменьшить размер передаваемых данных, а для ajax-ориентированного проекта бонусом пойдет еще и уменьшение размера всех ajax-данных передаваемых клиенту.

Это интересно:








версия для печатиРаспечатать статью


Вернуться в раздел: Programming / ASP.NET


Реклама:
Читать наc на:

Add to Google
Читать в Яндекс.Ленте






Rambler's Top100
© Copyright 1998-2012 Александр Томов. All rights reserved.