我已经看到了许多将 GZIP/DEFLATE 压缩添加到 ASP.Net MVC 输出的选项,但它们似乎都在动态应用压缩..因此不利用缓存压缩内容。
任何启用缓存压缩页面输出的解决方案?最好在代码中,以便MVC代码可以检查页面是否发生了变化,如果没有,则将预压缩的缓存内容发送出去。
这个问题确实也适用于常规的 asp.net。
我已经看到了许多将 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、Classic 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")]
有关该主题的完整介绍,请参阅使用输出缓存提高性能。主要建议是在应该应用缓存的 Action上使用 [ OutputCache ] 属性。
您可以创建一个缓存属性:
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;
}
}
使用命名空间
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());