onsdag den 10. oktober 2012

Komprimering af dit webindhold i MVC (GZIP / Deflate)




Boob deflate billede?

Når dine sider sendes afsted over din forbindelse så er der utroligt meget pladsspild, fordi der i vores html (tekstfiler) er meget spildplads. Vi vil gerne have det formateret pænt og læseligt, men er faktisk slet ikke nødvendigt for ens side og gør bare at den fylder mere.
Du kan nemt gå fra 52kb til 7kb som altså betyder meget. Dette er selvfølgelig forskelligt alt efter hvad indhold du har på din side, men uanset hvad er der besparelser at få.

Derfor kan du komprimere dit indhold.
Dette kan du gøre i web.config

<system.webServer>
   
<urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer> 

Eller du kan lave filtre du kan dekorere dine Controller actions med.

using System.Web;
using System.Web.Mvc;

public class CompressFilter : ActionFilterAttribute
    //FilterExecutingContext filterContext
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase request = filterContext.HttpContext.Request;

        string acceptEncoding = request.Headers["Accept-Encoding"];

        if (string.IsNullOrEmpty(acceptEncoding)) return;

        acceptEncoding = acceptEncoding.ToUpperInvariant();

        HttpResponseBase response = filterContext.HttpContext.Response;

        if (acceptEncoding.Contains("GZIP"))
        {
            response.AppendHeader("Content-encoding", "gzip");
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
        }
        else if (acceptEncoding.Contains("DEFLATE"))
        {
            response.AppendHeader("Content-encoding", "deflate");
            response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
        }
    }
}

Her er det vigtigt GZIP ligger øverst fordi den bruger en 10byte header og lidt andre ting til at lave fejlkorrigering og fejlcheck på den komprimerede stream, hvor deflate ikke gør det. Så hvis browseren understøtter det så lad den for gud skyld bruge den lille mikro smule mere plads på at sikre at data er validt.
Dette gøres således:

a gzip file/stream contains:
- a 10-byte header, containing a magic number, a version number and a time stamp
- optional extra headers, such as the original file name,
- a body, containing a DEFLATE-compressed payload
- an 8-byte footer, containing a CRC-32 checksum and
  the length of the original uncompressed data

Hvis du har fået mere interesse for dette så se nærmere her: http://weblogs.asp.net/rashid/archive/2008/03/28/asp-net-mvc-action-filter-caching-and-compression.aspx

LIG DOG MÆRKE TIL NEDERST PÅ SIDEN MED ORDER

You can also apply both these filter in the same action method, like the following:
[CompressFilter(Order = 1)]
[CacheFilter(Duration = 60, Order = 2)]
public void Category(string name, int? page)

her er Order meget vigtig.
Dette er fordi du fortæller her at Compress skal ske først (Order = 1) (så den går fra 52kb til 7kb), og det næste (Order = 2) er at den skal cache den compressede udgave så den ikke cacher en version der fylder 52kb i stedet for 7kb for så enten skal den compresses igen og tage tid og maskinkræft, eller også leverer den bare en 52kb fil afsted i stedet for den på 7kb.
Duration er det antal sekunder den skal caches.

Ingen kommentarer:

Send en kommentar

Kan du lide mit indlæg, har en kommentar, forslag eller andet på hjerte så skriv venligst