繁体   English   中英

ASP.NET MVC - 压缩 + 缓存

[英]ASP.NET MVC - compression + caching

我已经看到了许多将 GZIP/DEFLATE 压缩添加到 ASP.Net MVC 输出的选项,但它们似乎都是即时应用压缩的......因此不会利用缓存压缩的内容。

任何启用压缩页面输出缓存的解决方案? 最好在代码中,以便 MVC 代码可以检查页面是否已更改,如果未更改,则发送预压缩的缓存内容。

这个问题确实也适用于常规的 asp.net。

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

使用使用属性的缓存选项(对于 MVC),并且不要考虑压缩,因为 IIS/IISExpress 如果启用它会自动压缩您的输出。

就其工作方式而言,mvc 不支持缓存单个片段或部分输出(部分内容缓存)。 如果您想要这个,请考虑使用 CloudFlare 之类的服务(还有其他类似 CF 的服务吗?)。 它会自动缓存您的输出并缓存您的输出片段,并提供许多其他性能和安全改进,而无需更改您的代码。

如果这不是您的选择,那么您仍然可以使用 IISpeed(它是 Google 的 mod_pagespeed 的 IIS 端口)。 它提供了一些有趣的设置,如空格去除、内联 css 和 js 压缩、js 文件合并等。

CF 和 IISpeed 都不关心您的站点是如何构建的,它们在 http/html 级别上工作,因此它们都可以在 MVC、经典 ASP.NET、php 甚至原始 html 文件上工作。

您可以创建一个属性,如

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");  
        }  
    }  
} 

Global.asax.cs 中添加条目

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

然后您可以将此属性用作:

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

您可以从 Github 下载工作示例: https : //github.com/ctesene/TestCompressionActionFilter

链接似乎与您的要求非常接近。 它缓存压缩的动态生成的页面。 尽管该示例使用了 Web 表单,但它可以通过使用 OutputCache 属性来适应 MVC

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

您可以创建一个缓存属性:

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;
    }
}

有关该主题的完整介绍,请参阅使用输出缓存提高性能 主要建议是在应应用缓存的 Action上使用 [ OutputCache ] 属性。

使用命名空间

using System.Web.Mvc;

using System.IO.Compression;

在你的主项目中创建 ClassName.cs

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(_response.Filter == null) return;
            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);
            }
        }
    }

--- 并添加 global.asax.cs

GlobalFilters.Filters.Add(new CompressAttribute());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM