11

He visto una serie de opciones para agregar la compresión GZIP/DEFLATE a la salida ASP.Net MVC, pero todas parecen aplicar la compresión sobre la marcha ... por lo tanto, no lo haga aprovechar el almacenamiento en caché del contenido comprimido.ASP.NET MVC - compresión + almacenamiento en caché

¿Alguna solución para habilitar el almacenamiento en caché de la salida de página comprimida? Preferiblemente en el código, para que el código MVC pueda verificar si la página ha cambiado y enviar el contenido precomprimido en caché si no es así.

Esta pregunta realmente podría aplicarse a asp.net regular también.

+0

¿Quieres decir como el almacenamiento en caché la respuesta comprimida en 'System.Web.Cache'? – bzlm

+0

Quizás, o cualquier otra solución que logre esto. –

+0

Ninguna de las respuestas hasta ahora, aunque informativa en otros aspectos, parece abordar el contenido de compresión _en_la memoria caché contra el contenido _servado desde_ la memoria caché. Si piensa en una presentación de UG en caché ASP.NET, ¿ha considerado escribir un proveedor de caché personalizado? – J0e3gan

Respuesta

4
[Compress] 
[OutputCache(Duration = 600, VaryByParam = "*", VaryByContentEncoding="gzip;deflate")] 
public ActionResult Index() 
{ 
    return View(); 
} 
+2

¿Alguna documentación sobre esto? parece exactamente lo que estoy buscando. –

+0

Me encantaría ver más información sobre esto, no he podido hacer que el trabajo attrib "Compress" funcione –

0

Se puede crear un atributo de caché:

public class CacheAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache; 

     if (Enabled) 
     { 
      cache.SetExpires(System.DateTime.Now.AddDays(30)); 
     } 
     else 
     { 
      cache.SetCacheability(HttpCacheability.NoCache); 
      cache.SetNoStore(); 
     } 
    } 

    public bool Enabled { get; set; } 

    public CacheAttribute() 
    { 
     Enabled = true; 
    } 
} 
+0

¿Cómo funciona la compresión? –

+0

Lo siento, no entendí esa parte de la pregunta. Puede consultar esto en http://weblogs.asp.net/rashid/archive/2008/03/28/asp-net-mvc-action-filter-caching-and-compression.aspx. Todavía está realizando una compresión sobre la marcha, pero está basada en atributos, lo que le brinda más opciones de selección y selección que una solución para todo el servidor. –

3

Utilice las opciones de almacenamiento en caché utilizando atributos (para MVC), y no piense en la compresión ya que IIS/IISExpress comprime automáticamente su resultado si lo habilita.

la forma en que funciona, mvc no permite el almacenamiento en caché de fragmentos individuales o partes de salida (almacenamiento en caché de contenido parcial). si quieres esto, considera usar un servicio como CloudFlare (¿hay otro como CF?). guarda en caché automáticamente su salida y almacena en caché los fragmentos de su salida y proporciona muchas otras mejoras de rendimiento y seguridad, todo sin un cambio en su código.

Si esta no es una opción para usted, aún puede usar IISpeed ​​(es un puerto IIS de la versión de la velocidad de la página de Google). Proporciona algunas configuraciones interesantes como la eliminación de espacios en blanco, la compresión de css y js en línea, la fusión de archivos js y muchos otros.

Tanto CF como IISpeed ​​no se preocupan por cómo está construido su sitio, trabajan en el nivel http/html, por lo que ambos trabajan en MVC, Classic ASP.NET, php o incluso en archivos html sin formato.

+1

una última, tenga cuidado cuando use 'Vary' ya que puede romper el comportamiento de almacenamiento en caché de algunas versiones antiguas de IE. – edokan

1

Se puede crear un atributo como

public class EnableCompressionAttribute : ActionFilterAttribute 
{ 
    const CompressionMode Compress = CompressionMode.Compress; 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     HttpRequestBase request = filterContext.HttpContext.Request; 
     HttpResponseBase response = filterContext.HttpContext.Response; 
     string acceptEncoding = request.Headers["Accept-Encoding"]; 
     if (acceptEncoding == null) 
      return; 
     else if (acceptEncoding.ToLower().Contains("gzip")) 
     { 
      response.Filter = new GZipStream(response.Filter, Compress); 
      response.AppendHeader("Content-Encoding", "gzip"); 
     } 
     else if (acceptEncoding.ToLower().Contains("deflate")) 
     { 
      response.Filter = new DeflateStream(response.Filter, Compress); 
      response.AppendHeader("Content-Encoding", "deflate"); 
     } 
    } 
} 

Añadir entrada en Global.asax.cs

 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
     { 
      filters.Add(new EnableCompressionAttribute()); 
     } 

continuación, puede utilizar este atributo como:

[EnableCompression] 
    public ActionResult WithCompression() 
    { 
     ViewBag.Content = "Compressed"; 
     return View("Index"); 
    } 

Usted puede descargar el ejemplo de trabajo de Github: https://github.com/ctesene/TestCompressionActionFilter

+0

¿Es compatible ** con el almacenamiento en caché ** la versión comprimida de la página en lugar de volver a comprimir cada solicitud? – AaronLS

+0

Sí, el atributo se aplica al método del controlador, por lo tanto, la "respuesta" se comprime desde el lado del servidor. No entendí qué quiere decir con "volver a comprimir la solicitud". –

+0

Si la compresión ocurre o no en cada solicitud, es ineficiente: "Solicitar recibidos-> Recuperar página en caché-> Comprimir página almacenada en caché", frente a "Solicitar recepción-> Recuperar página en caché (que ya está comprimida)". – AaronLS

1

Este link parece bastante cerca de lo que necesita. Almacena en caché páginas comprimidas generadas dinámicamente. Aunque el ejemplo se utilizan los formularios Web, Se puede adaptar a MVC mediante el uso de un OutputCache de atributo

[OutputCache(Duration = 600, VaryByParam = "*", VaryByContentEncoding="gzip;deflate")] 
Cuestiones relacionadas