Разгони свой сайт

Проект создан как справочный ресурс по методам уменьшения времени загрузки страницы и загрузки сайта у конечного пользователя

English Russian

Проверить скорость загрузки

http://

Статьи

Автор: Владимир aka XaocCPS
Опубликована: 27 мая 2008, habrahabr.ru/blog/net/43205.html

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

Сжатие 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"))

  {
    // deflate
    app.Response.Filter = new DeflateStream(prevUncompressedStream,
      CompressionMode.Compress);
    app.Response.AppendHeader("Content-Encoding",
      "deflate");

  }
}
</script>

Основные плюсы данного метода:

  • расположение в 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");

        }
      }
    }

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

protected void Page_Load(object sender, EventArgs e)

{
  HtmlUtil.GZipEncodePage();
}

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

Плюсы этого подхода:

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

Минусы:

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

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

Послесловие

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

Приведу некоторые данные:

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

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

Читать дальше

Все комментарии (habrahabr.ru)

Обратная связь

Если у вас возникли какие-либо вопросы или пожелания по работе Web Optimizator, пожалуйста, поделитесь ими, используя контактную информацию.

Спасибо за использование сервиса!

Ускорение сайта «под ключ»
TEXTSTYLE

Книги по оптимизации

Yet Another cSS selector

Ссылки по теме

Техника CSS sprites

Приемы для JavaScript

Хитрости для CSS

Облако сайтов

Вебсайтов сейчас: 1, сегодня: 410, всего: 136915, последний: school-74.ru
© 2008–2010 WEBO Software | Карта сайта | RSS (читают 750)

This work is licensed under a Creative Commons Attribution 3.0 Unported License.