简体   繁体   English

ASP.NET MVC - 压缩 + 缓存

[英]ASP.NET MVC - compression + caching

I've seen a number of options for adding GZIP/DEFLATE compression to ASP.Net MVC output, but they all seem to apply the compression on-the-fly.. thus do not take advange of caching the compressed content.我已经看到了许多将 GZIP/DEFLATE 压缩添加到 ASP.Net MVC 输出的选项,但它们似乎都是即时应用压缩的......因此不会利用缓存压缩的内容。

Any solutions for enabling caching of the compressed page output?任何启用压缩页面输出缓存的解决方案? Preferably in the code, so that the MVC code can check if the page has changed, and ship out the precompressed cached content if not.最好在代码中,以便 MVC 代码可以检查页面是否已更改,如果未更改,则发送预压缩的缓存内容。

This question really could apply to regular asp.net as well.这个问题确实也适用于常规的 asp.net。

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

Use caching options using attributes (for MVC), and do not think about compression since IIS/IISExpress automatically compresses your output if you enable it.使用使用属性的缓存选项(对于 MVC),并且不要考虑压缩,因为 IIS/IISExpress 如果启用它会自动压缩您的输出。

the way it works, mvc does not enable caching of individual fragments or parts of output (partial content caching).就其工作方式而言,mvc 不支持缓存单个片段或部分输出(部分内容缓存)。 if you want this, consider using a service like CloudFlare (is there any other like CF?).如果您想要这个,请考虑使用 CloudFlare 之类的服务(还有其他类似 CF 的服务吗?)。 it automatically caches your output and caches fragments of your output and provides many other performance and security improvements, all without a change in your code.它会自动缓存您的输出并缓存您的输出片段,并提供许多其他性能和安全改进,而无需更改您的代码。

If this is not an option for you, then you still may use IISpeed (it is a IIS port of Google's mod_pagespeed).如果这不是您的选择,那么您仍然可以使用 IISpeed(它是 Google 的 mod_pagespeed 的 IIS 端口)。 It provides some interesting settings like whitespace removal, inline css and js compression, js file merge and many other.它提供了一些有趣的设置,如空格去除、内联 css 和 js 压缩、js 文件合并等。

Both CF and IISpeed does not care how your site is built, they work on http/html level, so they both work on MVC, Classic ASP.NET, php or even raw html files. CF 和 IISpeed 都不关心您的站点是如何构建的,它们在 http/html 级别上工作,因此它们都可以在 MVC、经典 ASP.NET、php 甚至原始 html 文件上工作。

You can create a attribute like您可以创建一个属性,如

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

Add entry in Global.asax.csGlobal.asax.cs 中添加条目

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

Then you can use this attribute as:然后您可以将此属性用作:

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

You can download working example from Github: https://github.com/ctesene/TestCompressionActionFilter您可以从 Github 下载工作示例: https : //github.com/ctesene/TestCompressionActionFilter

This link seems fairly close to what you require.链接似乎与您的要求非常接近。 It caches compressed dynamically generated pages.它缓存压缩的动态生成的页面。 Although the example uses Web forms, It can be adapted to MVC by using an OutputCache attribute尽管该示例使用了 Web 表单,但它可以通过使用 OutputCache 属性来适应 MVC

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

You could create a Cache Attribute:您可以创建一个缓存属性:

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

See Improving performance with output caching for a full introduction on the subject.有关该主题的完整介绍,请参阅使用输出缓存提高性能 The main recommendation is to use the [ OutputCache ] attribute on the Action to which caching should be applied.主要建议是在应应用缓存的 Action上使用 [ OutputCache ] 属性。

use namespace使用命名空间

using System.Web.Mvc;

using System.IO.Compression;

create ClassName.cs in you main project在你的主项目中创建 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);
            }
        }
    }

--- and add in global.asax.cs --- 并添加 global.asax.cs

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

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

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