Jak włączyć kompresję gzip podczas korzystania z MVC3 w usługach IIS7?

101

Czy ktoś wie, jak włączyć kompresję gzip w MVC 3? Używam IIS7.

Wynik audytu Google Chrome:

  1. Włącz kompresję gzip (4)
  2. Kompresja następujących zasobów za pomocą gzip może zmniejszyć ich rozmiar transferu o około dwie trzecie (~ 92,23 KB):
  3. / moja_domena / może zaoszczędzić ~ 1,53 KB
  4. jquery-1.4.4.min.js mógłby zaoszczędzić ~ 51.35KB
  5. Cufon.js mógłby zaoszczędzić ~ 11.89KB
  6. Futura.js mógłby zaoszczędzić ~ 27.46KB
imarkic84
źródło
Not quiet a duplicate: stackoverflow.com/q/552317/712526
jpaugh

Odpowiedzi:

143

Możesz skonfigurować kompresję za pomocą web.configpliku w następujący sposób:

<system.webServer>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>

Dokumentację tego elementu konfiguracji można znaleźć pod adresem iis.net/ConfigReference . To jest odpowiednik:

  1. Otwieranie Internetowych usług informacyjnych (Menedżer IIS)
  2. Poruszanie się po widoku drzewa po lewej stronie, aż dotrzesz do katalogu wirtualnego, który chcesz zmodyfikować
  3. Wybór odpowiedniego katalogu wirtualnego, tak aby tytuł prawego panelu stał się nazwą wspomnianego katalogu wirtualnego.
  4. Wybranie opcji „Kompresja” w sekcji „IIS” w panelu po prawej stronie
  5. Zaznacz obie opcje i wybierz „Zastosuj” w sekcji „Działania” po prawej stronie.

Uwaga: (jak wskazano w komentarzach) Musisz upewnić się, że zainstalowano kompresję dynamiczną Http, w przeciwnym razie ustawienie doDynamicCompression="true"nie będzie miało żadnego efektu. Najszybszym sposobem na to jest:

  1. Start> Wpisz optionalfeatures(jest to najszybszy sposób, aby dostać się do okna „Włącz lub wyłącz funkcje systemu Windows”)
  2. Przejdź do Internet Information Services> World Wide Web Services> Performance Features w widoku drzewa „Windows Features”
  3. Upewnij się, że opcja „Kompresja zawartości dynamicznej” jest zaznaczona
  4. Kliknij „OK” i poczekaj, aż system Windows zainstaluje składnik
Obrabować
źródło
11
Warto zauważyć, że aby to zadziałało, musisz mieć zainstalowaną opcję Http Compression Dynamic IIS. Link do konfiguracji w tej odpowiedzi zawiera szczegółowe informacje.
Caleb Vear
16
Na Windows Server 2008 optionalfeaturesnie działał dla mnie. Zamiast tego przejdź do Menedżera serwera> Role> Przewiń do serwera sieci Web (IIS)> kliknij Dodaj usługi ról. Teraz upewnij się, że serwer WWW> Wydajność> Kompresja zawartości statycznej i Kompresja zawartości dynamicznej są zainstalowane.
Rory,
1
Należy pamiętać, że może to zepsuć nagłówek hosta „Vary:”. Więcej informacji: stackoverflow.com/questions/5372052/ ...
jjxtra
2
Przynajmniej z mojego doświadczenia wynika, że ​​kompresuje to wszystko, ALE dane wyjściowe kontrolerów MVC. Z jakiegoś powodu zwracają HTML bez żadnej kompresji gzip.
Chris Moschini
1
Uwaga !!! Kompresja dynamiczna IIS usuwa nagłówki Vary, to błąd lub funkcja, nie wiem, ale implementacja niestandardowego filtru ma większy sens, jeśli chcesz, aby pamięć podręczna działała poprawnie.
Akash Kava,
31

Możesz to zrobić w kodzie, jeśli wolisz to zrobić. Zrobiłbym podstawowy kontroler, z którego dziedziczy każda kontrolka i ozdobiłbym go poniższym atrybutem.

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
        if (string.IsNullOrEmpty(encodingsAccepted)) return;

        encodingsAccepted = encodingsAccepted.ToLowerInvariant();
        var response = filterContext.HttpContext.Response;

        if (encodingsAccepted.Contains("deflate"))
        {
            response.AppendHeader("Content-encoding", "deflate");
            response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
        }
        else if (encodingsAccepted.Contains("gzip"))
        {
            response.AppendHeader("Content-encoding", "gzip");
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
        }
    }
}
NetProvoke
źródło
2
@JustAnotherUserYouMayKnow - zależy od tego, jak obsługujesz swoje zasoby; jeśli wskazujesz bezpośrednio na pliki na serwerze, to nie, jednak jeśli obsługujesz je przez akcje (na co pozwala nasz system zarządzania zasobami), to działa znakomicie. BTW Rick Strahl zaktualizował to, aby umożliwić sprawdzanie, czy klient faktycznie obsługuje gzip przed kompresją
Paul Carroll,
4
Zauważ, że w przypadku przekierowania ważne jest, aby zabezpieczyć się przed filterbyciem null. Użyłem var response = ...;if( response == null || response.Filter == null)return;.
Travis J
2
Możesz też użyć gzipnajpierw zamiast deflate, przeczytaj więcej tutaj: stackoverflow.com/a/9856879/1026459
Travis J
Usługi IIS buforują skompresowane pliki, więc nie będą musiały ich ponownie kompresować w celu uzyskania lepszej wydajności. Korzystaj z usług IIS, jeśli możesz, i używaj tego podejścia tylko wtedy, gdy kompresja usług IIS nie jest dostępna.
Muhammad Rehan Saeed
1
Żadne z tych rozwiązań nie działa na MVC5, IIS 8.5, .Net 4.5 Localhost. Co mam zrobić, jakieś sugestie?
aadi1295
12

Kompresja jest włączona / wyłączona na poziomie serwera. Zobacz moduł kompresji IIS w konsoli zarządzania iis.

Oto instrukcje dotyczące usług IIS z witryny firmy Microsoft.

nakhli
źródło
1
Możesz to również ustawić w pliku web.config
Jack Marchetti