Подтвердить что ты не робот

ASP.NET MVC - сжатие + кэширование

Я видел несколько вариантов добавления сжатия GZIP/DEFLATE к выходу ASP.Net MVC, но все они, похоже, применяют сжатие "на лету". Таким образом, не следует использовать кэширование сжатого содержимого.

Любые решения для обеспечения кэширования сжатого вывода страницы? Предпочтительно в коде, чтобы код MVC мог проверить, изменилась ли страница, и отправляет предварительно сжатый кешированный контент, если нет.

Этот вопрос действительно применим и к обычным asp.net.

4b9b3361

Ответ 1

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

Ответ 2

Используйте параметры кеширования с помощью атрибутов (для MVC) и не думайте о сжатии, так как IIS/IISExpress автоматически сжимает ваш вывод, если вы его включите.

как это работает, mvc не позволяет кэшировать отдельные фрагменты или части вывода (частичное кэширование содержимого). если вы хотите этого, подумайте о том, чтобы использовать такую ​​услугу, как CloudFlare (есть ли какой-либо другой, такой как CF?). он автоматически кэширует ваш вывод и кэширует фрагменты вашего вывода и обеспечивает многие другие улучшения производительности и безопасности, без изменения вашего кода.

Если это не вариант для вас, вы все равно можете использовать IISpeed ​​(это порт IIS для Google mod_pagespeed). Он предоставляет некоторые интересные настройки, такие как удаление пробелов, встроенное сжатие css и js, слияние файлов js и многие другие.

Как CF, так и IISpeed ​​не заботятся о том, как создается ваш сайт, они работают на уровне http/html, поэтому оба они работают с MVC, классическим ASP.NET, php или даже сырыми файлами html.

Ответ 3

Вы можете создать такой атрибут, как

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

Ответ 5

Вы можете создать атрибут кэша:

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