[英]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.