Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

Przyspieszamy ASP.NET - kompresja HTTP

Wyobraźmy sobie rozwiązanie, które:

  • pozwala na zmniejszenie transferu wykorzystywanego przez witrynę,
  • umożliwia szybsze dostarczenie treści użytkownikowi,
  • wymaga bardzo małego nakładu pracy przy wdrożeniu,
  • w niedużym stopniu wpływa na wydajność serwera oraz
  • jest od dawna wspierane przez wszystkie przeglądarki…

Zbyt piękne, żeby było prawdziwe? Nieprawda – takie rozwiązanie istnieje i nazywa się kompresja HTTP! Idea polega w skrócie, żeby odpowiedź na żądanie klienta skompresować przed wysłaniem, ograniczając jej rozmiar i czas przesyłania przez sieć. Efekt: wilk syty, owca cała – zmniejszamy transfer witryny (nasze koszty) i czas ładowania stron (lepszy odbiór przez użytkowników).

Jak to działa?

Przeglądarka wysyła do serwera żądanie, którego nagłówek wygląda mniej więcej tak:
image 
W tym nagłówku ważny jest nagłówek Accept-Encoding, w którym przeglądarka chwali się jakie rodzaje kodowania (czyt. kompresji) obsługuje. Dostępne są dwie standardowe metody: GZip oraz Deflate. Wówczas serwer wie, że może skompresować przesyłaną zawartość i że klient go zrozumie. Nagłówek odpowiedzi może wyglądać mniej więcej tak:
image 
Jak widać nagłówek Content-Encoding informuje klienta, jaka metoda kodowania (kompresji) została zastosowana do przesłania treści odpowiedzi.

A teraz rzecz najważniejsza. Kompresja HTTP oraz metody GZip i Deflate są częścią standardu HTTP/1.1 (opublikowanego w 1999r.) i wspierają je wszystkie współczesne przeglądarki – począwszy od IE 4.0 i Netscape 4.0.

Oczywiście, nie wszystko warto kompresować. O ile zawartość tekstowa (ASPX, HTML, JS, CSS) w wyniku kompresji zmniejsza swój rozmiar średnio o 75% (staje się 4 razy mniejsza!), to w przypadku plików już skompresowanych (grafika, wideo, docx, itd.) zwykle uzyskamy efekt zerowy.

Nie ma róży bez kolców? Niekoniecznie. Jedyną wadą kompresji HTTP jest trochę większe zużycie procesora, potrzebne do skompresowania wysyłanej treści. Jednakże w większości rozwiązań webowych wąskie gardło stanowi szybkość dysków lub ilość pamięci operacyjnej, podczas gdy czasu procesora mamy pod dostatkiem (oczywiście są wyjątki).

Kompresja HTTP z punktu widzenia serwera

Wyróżniamy dwa rodzaje kompresji z punktu widzenia serwera:

  1. Kompresja statyczna, która dotyczy statycznych plików serwowanych bezpośrednio przez serwer (np. pliki HTML, JS, CSS). Ponieważ ich zawartość nie zmienia się w czasie, to serwer może raz skompresowany plik zachować w swoim cache’u, dzięki czemu przy następnym żądaniu nie musi przeprowadzać kompresji na nowo.
  2. Kompresja dynamiczna, dotycząca zawartości generowanej dynamicznie (ASPX, ASMX, ASHX, AXD, itp.). W tej sytuacji każda odpowiedź jest inna i serwer musi za każdym razem przeprowadzać kompresję.

Kompresja HTTP na IIS 6

Uruchomienie kompresji w II 6 możliwe jest albo z poziomu konsoli administracyjnej albo wykorzystując odpowiedni skrypt. Wyczerpująco opisuje to artykuł “Enabling HTTP Compression (IIS 6.0)”, więc nie ma sensu, żebym go tutaj przepisywał. Natomiast jeśli chodzi o konfigurację to polecam tekst “Using HTTP Compression for Faster Downloads (IIS 6.0)”.

Z ważnych informacji – IIS 6 pozwala na wybór, kiedy stosowana jest kompresja. Niestety, to rozróżnienie bazuje tylko i wyłącznie na rozszerzeniach plików. W przypadku zawartości statycznej nie stanowi to problemu. Natomiast w przypadku treści generowanej dynamicznie jest to spore ograniczenie. Najlepszym przykładem mogą być tutaj HTTP Handlers (rozszerzenie ASHX), w przypadku których typ dostarczanej zawartości zależy tylko i wyłącznie od konkretnego handlera.

Kompresja HTTP na IIS 7

W przypadku IIS 7 uruchomienie kompresji wymaga dwóch kroków. Po pierwsze musimy upewnić się, iż mamy zainstalowane odpowiednie składniki serwera (“Kompresja zawartości statycznej” i “Kompresja zawartości dynamicznej”). Po drugie musimy włączyć kompresję w pliku web.config lub z poziomu konsoli IIS Manager. Uruchomienie i konfigurację kompresji HTTP na IIS 7 bardzo dobrze opisuje artykuł “HTTP Compression ”.

IIS 7, w odróżnieniu od poprzedniej wersji, pozwala decydować o stosowaniu kompresji w oparciu o typ MIME zawartości (nagłówek Content-Type odpowiedzi). Dzięki temu, zwłaszcza w przypadku zawartości dynamicznej mamy dostępne znacznie precyzyjniejsze narzędzie.

Z ciekawych możliwości wprowadzonych w IIS 7 jest możliwość określenia progów zużycia procesora, dla których wyłączana jest kompresja oraz włączana jest ponownie (jeśli taka możliwość istniała w IIS 6, to poprawcie mnie).

Kompresja HTTP ręcznie

Czasami może zdarzyć się, iż nie możemy włączyć kompresji bezpośrednio na serwerze. Najczęściej bywa tak w przypadku hostingu aplikacji ASP.NET (shared hosting). Wówczas w interesie hostingodawcy (wg GIODO takie słowo istnieje ;)) jest abyśmy z kompresji nie korzystali, gdyż za transfer płacimy, a za czas procesora zwykle nie. Istnieje jednak programistyczne obejście pozwalające włączyć kompresję przynajmniej w tych sytuacjach, gdy żądanie nie jest obsługiwane bezpośrednio przez serwer i dociera do silnika ASP.NET (w przypadku IIS 6 jest to tylko zawartość dynamiczna; w przypadki IIS 7 zależy to od konfiguracji).

Oto przykładowy fragment pliku Global.asax.cs uruchamiający kompresję HTTP ręcznie dla stron ASP.NET:

   1: protected void Application_BeginRequest(object sender, EventArgs e)
   2: {
   3:     if (this.Request.Headers["Accept-Encoding"] != null
   4:         && this.Request.Headers["Accept-Encoding"].Contains("gzip")
   5:         && this.Request.Path.ToLower().EndsWith(".aspx"))
   6:     {
   7:         this.Response.Filter = new System.IO.Compression.GZipStream(this.Response.Filter, System.IO.Compression.CompressionMode.Compress, true);
   8:         this.Response.AddHeader("Content-encoding", "gzip");
   9:     }
  10: }

Podsumowanie

Kompresja HTTP:

  • wchodzi w skład standardu HTTP/1.1,
  • jest wpierana przez praktycznie wszystkie współczesne przeglądarki,
  • wymaga bardzo małego nakładu pracy do uruchomienia,
  • zmniejsza transfer wykorzystywany przez witrynę,
  • skraca czas ładowania stron,
  • ale zwiększa zużycie procesora.

Czy warto? A czy szybciej biega się z pięćdziesięciokilogramowym workiem na plecach czy bez?

Opublikowane 22 sierpnia 2009 00:34 przez jakubin

Komentarze:

# Jakub Binkowski - dot or not : Przyspieszamy ASP.NET - kompresja HTTP

Dziękujemy za publikację - Trackback z dotnetomaniak.pl

22 sierpnia 2009 07:05 by dotnetomaniak.pl

# re: Przyspieszamy ASP.NET - kompresja HTTP

Wg mnie warto. Procesory są dziś dość szybkie a przepustowość łącza czasem nadal stanowi problem. Lepiej dać trochę więcej "roboty" dla szybkiego CPU niż pchać dużo więcej danych przez ograniczone łączę.

22 sierpnia 2009 07:07 by Paweł Łukasik

# re: Przyspieszamy ASP.NET - kompresja HTTP

fajny tut, bede musial sie tym pobawic, dzieki

22 sierpnia 2009 17:13 by binary

# re: Przyspieszamy ASP.NET - kompresja HTTP

ustawilem wszystko wedlug instrukcji w IIS ale w folderze ktory wskazalem jako tem (dalem na nim Full Control dla grupy IIS_WPG) nie odkladaja sie zadne pliki. Yslow tez nie pokazuje zeby cokolwiek przyspieszylo. Robie to na IIS 6.

Ktos z Was wlaczal to u siebie na IIS 6?

Pozdr.

22 sierpnia 2009 18:17 by binary

# re: Przyspieszamy ASP.NET - kompresja HTTP

Oczywiście, że warto i trudno mi sobie wyobrazić, stronę, która ma dużą oglądalność i nie wykorzystuje gzip'a.

W sumie, równie proste jak w PHP :).

22 sierpnia 2009 18:21 by Dawid Pośliński

# re: Przyspieszamy ASP.NET - kompresja HTTP

@binary:

Przed chwilą ściągnąłem sobie obraz czystej Win2003 i udało mi się odpalić kompresję. Na początku miałem ten sam problem co Ty i zrobiłem dwie rzeczy (ale nie wiem, która pomogła):

1) iisreset

2) wszedłem na witrynę z zewnątrz.

Po tych dwóch krokach wszystko zaczęło działać. Jakbyś miał dalej problemy, to napisz do mnie -> jakub [at] binkowski.com.pl - może razem coś zaradzimy. Powodzenia!

22 sierpnia 2009 22:07 by jakubin

# re: Przyspieszamy ASP.NET - kompresja HTTP

a co w przypadku kiedy na przyklad na stronie chcemy wygenerowac jakiegos xml'a i pozniej zapisac go jako attachment ??? tresc tego xml'a rowniez zostanie spakowana po czym zapisana na dysk ??? dobrze mysle ???

26 sierpnia 2009 21:53 by szepiet

# re: Przyspieszamy ASP.NET - kompresja HTTP

@szepiet:

Jeżeli XML generujesz i zapisujesz na dysku gdzieś w katalogu witryny (np. ~/Files/0001.xml) a następnie dajesz użytkownikom jawnie link do tego pliku (www.mojastrona.com/Files/0001.xml), to zostanie on skompresowany i zapisany na dysku (bo tak działa kompresja statyczna).

Natomiast jeżeli utworzysz własny HTTP handler, który dynamicznie generuje takiego XMLa i wysyła do klienta, to w grę w chodzi kompresja dynamiczna, która nie cache'uje danych na dysku.

26 sierpnia 2009 23:01 by jakubin

# re: Przyspieszamy ASP.NET - kompresja HTTP

Czy warto, to zalezy ;) Jak procesor ledwo zipie, a lacze ma duza przepustowosc to lepiej nie kompresowac. Nie ma sensu rowniez kompresowac juz skompresowanych plikow (zip, jpg, mpeg...).

Jesli jest mamy doczynienia z plikiem statycznym (lub danymi, ktore rzadko sie zmieniaja) to najlepiej sobie zapisac rowniez jego skompresowana kopie (i sprawdzac date ostaniej modyfikacji w celu okreslenia czy wymagana jest powtorna kompresja - dane sie zmienily) i w zalezniosci czy przegladarka obsluguje kompresje czy tez nie wysylac jej odpowiedni plik (bo i po co za kazdym razem kompresowac to samo).

Ale najwazniejsze jast cache'owanie, a nie zadna kompresja. Trzeba cache'owac wszystko co sie da :) To jest podstawa przyspieszania ASP.NET.

12 września 2009 14:32 by Pasibrzuch

# Finasteride 1mg.

Finasteride drug profile and news. Finasteride. 1mg finasteride for bph. Generic finasteride.

16 grudnia 2009 16:53 by Finasteride.

# re: Przyspieszamy ASP.NET - kompresja HTTP

Świetny artykuł!

Mam jedno pytanko. Rozumiem, że przy dynamicznym (ręcznym) włączaniu kompresji (tak jak to przedstawiłeś w pliku Global.asax.cs) nie trzeba nic konfigurować na IIS ? Wystarczy odpowiednie oprogramowanie tego?

Dobra robota!

Pozdrawiam serdecznie!

10 kwietnia 2010 16:03 by eiter
Komentarze anonimowe wyłączone

About jakubin

MVP w kategorii C#, MCP. Aktualnie pracuje w Webstruments.pl jako programista C#.