¿Cómo implementar la compresión GZip en ASP.NET?

81

Estoy tratando de implementar la compresión GZip para mi página asp.net (incluidos mis archivos CSS y JS). Probé el siguiente código, pero solo comprime mi página .aspx (lo encontré en YSlow )

HttpContext context = HttpContext.Current;
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;

El código anterior solo comprime mi código de página .aspx (marcado), no los archivos CSS y JS que se incluyen como archivos externos. Por favor, dígame cómo puedo implementar la compresión GZip en ASP.NET usando código (porque estoy en un servidor de alojamiento compartido donde no tengo acceso a las configuraciones del servidor IIS). Y también en el código anterior no obtengo las dos últimas líneas, por qué se usan y cuál es el propósito de estas líneas. ¡Por favor explique!

Prashant
fuente
No es un duplicado: stackoverflow.com/questions/6992524
jpaugh

Respuestas:

28

Para comprimir archivos JS y CSS, en realidad debe manejar eso en el nivel de IIS, ya que estos archivos se procesan directamente sin el tiempo de ejecución de ASP.NET.

Puede hacer una asignación de extensión JSX y CSSX en IIS a aspnet_isapi.dll y luego aprovechar su código postal, pero es probable que IIS haga un mejor trabajo por usted.

El encabezado de codificación de contenido le dice al navegador que necesita descomprimir el contenido antes de procesarlo. Algunos navegadores son lo suficientemente inteligentes como para resolver esto de todos modos, según la forma del contenido, pero es mejor decirlo.

La configuración de caché de codificación de aceptación está ahí para que una versión en caché del contenido comprimido con gzip no se envíe a un navegador que solicitó solo texto / html.

Ben Scheirman
fuente
4
Hola @Ben, ¿Podría decirme cómo comprimir mis archivos usando IIS, cuáles son todas las configuraciones que tengo que realizar? Aunque no tengo acceso a las configuraciones de IIS, intentaré hacerlo. Por favor, dime cómo comprimir archivos usando IIS. ¡Gracias!
Prashant
4
stackoverflow.com/a/6992948/8479 detalla el simple cambio a web.config que se necesita para IIS7 o superior.
Rory
47

Aquí está la solución para archivos CSS y JavaScript. Agregue el siguiente código dentro de su archivo web.config:

  <httpCompression>
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>

Crédito: Cómo hacer GZip en ASP.NET y GoDaddy

dortzur
fuente
4
la última línea debe eliminarse
JeffT
cierto, pero en realidad agregaría la apertura <system.webServer> ... para que sepamos dónde poner la configuración.
Carlos R Balebona
Agregué el mismo código pero los archivos no se comprimen
Zeeshan Ahmad Khalil
¿Necesito agregar algo más?
Zeeshan Ahmad Khalil
16

esto puede ser útil para que lo pruebes, acepta desinflar y compresión gzip.

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (app.Context.CurrentHandler == null)
            return;

        if (!(app.Context.CurrentHandler is System.Web.UI.Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

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

        acceptEncoding = acceptEncoding.ToLower();

        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // deflate
            app.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
        else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
    } 
Nudier Mena
fuente
2
Muchas gracias por este código. Necesitaba gzip / desinflar el contenido de un sitio específico al que no tengo acceso a la consola IIS y esto me ayudó. Sin embargo, solo una pregunta: este código parece estar desinflando todos los archivos aspx y haciendo gzip en CSS y ScriptResources, pero no está haciendo gzip en ningún archivo .js. ¿Hay alguna forma de hacer eso? Gracias.
Rafael Merlin
Esto es incorrecto, ya que no se está manejando una instrucción de calidad como esto: gzip;q=0,deflate. singular.co.nz/2008/07/…
oligofren
11

La razón por la que solo está comprimiendo su archivo ASPX es que el código que ha escrito solo está incrustado en el archivo ASPX. Un archivo ASPX es una solicitud separada de cualquier contenido vinculado que contenga. Entonces, si tiene una página ASPX que contiene:

<img src="www.example.com\exampleimg.jpg" alt="example" />

Esto equivaldría a 2 solicitudes (además de las búsquedas de DNS) de su navegador a los recursos:

  1. para la página aspx y
  2. para la imagen contenida en la página aspx.

Cada solicitud tiene su propio vapor de respuesta. El código que ha publicado se adjunta solo al flujo de respuesta ASPX, por lo que solo se comprime su página ASPX. Las líneas 1 y 2 de su código publicado esencialmente toman el control del flujo de respuesta normal de la página e inyectan un código de "intermediario" que en este caso come y comprime el flujo de salida normal con un flujo GZip y lo envía por el cable.

Las líneas 3 y 4 están configurando los encabezados de respuesta. Todas las solicitudes y respuestas http tienen encabezados que se envían antes del contenido. Estos configuran la solicitud / respuesta para que el servidor y el cliente sepan qué se envía y cómo.

En este caso, la Línea 3 informa al navegador del cliente que el flujo de respuesta está comprimido a través de gzip y, por lo tanto, el navegador del cliente debe descomprimirlo antes de mostrarlo.

Y la línea 4 simplemente activa el encabezado Accept-Encoding de la respuesta. De lo contrario, esto no habría estado presente en la respuesta.

Hay módulos conectables que puede escribir / obtener y que le permiten comprimir un multitide de otro tipo MIME como * .js y * .css, pero es mejor que utilice la funcionalidad de compresión integrada de IIS.

No ha dicho qué versión de IIS está utilizando, pero si fuera IIS 7.0, sería necesario que incluyera algo como lo siguiente en la <system.webserver>sección de su archivo web.config:

<httpCompression> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> 
 <staticTypes>
         <add mimeType="text/*" enabled="true" />
      </staticTypes>
</httpCompression> 
<urlCompression doStaticCompression="true" /> 

..

Ricardo

intermension
fuente
Descripciones realmente impresionantes
Rakeshyadvanshi
3

En IIS7, todas las solicitudes van a .net, por lo que tendría que crear un HttpModule que agregara esos encabezados a todas las respuestas.

Sin IIS7, y en el alojamiento compartido, tendría que crear un controlador que mapeó una extensión de archivo .net que no está usando (como .asmx) y en web.config especificar que los archivos .asmx van a su HttpHandler que está configurado para reescribir la ruta a .jpg o lo que sea y establecer el encabezado allí también.

missaghi
fuente
2

Para responder a su última pregunta. Esas dos líneas establecen encabezados HTTP para la respuesta enviada al navegador. Content-Encodingle dice al navegador que la respuesta está codificada como gzip y necesita ser decodificada. La última línea se suma Accept-Encodingal encabezado Vary . Con esto, el navegador o los proxies pueden determinar si la respuesta fue única o si está influenciada por otros encabezados y ajustar su almacenamiento en caché.

gix
fuente
0

Agregue la extensión .aspx al archivo .css o .js. Utilice <% @ Page ContentType = "text / css"%> o javascript dentro del archivo para publicarlo con el tipo MIME correcto. & use URL Rewrite para ocultar esto de los navegadores del agente de usuario. El encabezado de respuesta de codificación de contenido se adjunta como gzip para transmitir que gzip es el método utilizado para realizar la compresión. Variar el encabezado de respuesta establecido en Accept-Encoding para que todos los cachés sepan qué página (comprimida o sin comprimir) debe servirse depende del encabezado Accept-Encoding de la solicitud. He elaborado sobre esto en https://stackoverflow.com/a/14509007/1624169

Chawathe Vipul S
fuente
0

Puede agregar lo siguiente a su archivo web.config dentro del <system.webServer>elemento:

<urlCompression doStaticCompression="true" doDynamicCompression="true" />

NOTA: Si está utilizando una versión anterior de IIS (inferior a la v7.5), es posible que desee establecer doDynamicCompression en falso porque el proceso consumía mucha CPU. Estos problemas se solucionaron en IIS 7.5.

Referencia: https://docs.microsoft.com/en-us/iis/configuration/system.webserver/urlcompression

Almiar
fuente
0

O hazlo con el archivo web.config

<system.webServer>
    <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </staticTypes>
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

O puede hacerlo a través de IIS. Para comprimir archivos JS y CSS, en realidad debe manejar eso en el nivel de IIS, ya que estos archivos se procesan directamente sin el tiempo de ejecución de ASP.NET.

Puede hacer una asignación de extensión JSX y CSSX en IIS a aspnet_isapi.dll y luego aprovechar su código postal, pero es probable que IIS haga un mejor trabajo por usted.

El encabezado de codificación de contenido le dice al navegador que necesita descomprimir el contenido antes de procesarlo. Algunos navegadores son lo suficientemente inteligentes como para resolver esto de todos modos, según la forma del contenido, pero es mejor decirlo.

La configuración de caché de codificación de aceptación está ahí para que una versión en caché del contenido comprimido con gzip no se envíe a un navegador que solicitó solo texto / html.

Código
fuente