Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ivan 165 posts 543 karma points
    Oct 23, 2012 @ 10:18
    Ivan
    0

    Caching .css and .js files.

    Hi guys.

    I would like to cache website .css and .js files, so that Google Speed Test gives it more points.

    How do I do that in Umbraco?

  • Ismail Mayat 4511 posts 10092 karma points MVP 2x admin c-trib
    Oct 23, 2012 @ 11:14
  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Oct 23, 2012 @ 11:42
    Alex Skrypnyk
    0

    Hello Ivan,

    Nice to meet Russian guy in this forum ))  Greeting from Ukraine.

    On our projects we use this handler for compressing and caching css and js.

        public const char DELIMITER = ',';
        public const bool ENABLEHTTPCOMPRESSION = true;
        public TimeSpan CacheDuration = TimeSpan.FromDays(20);
    
        public class ContentTypes
        {
            public const string CSS = "text/css";
            public const string JS = "application/x-javascript";
            public const string ERROR = "text/plain";
        }
    
        public class Folders
        {
            // customize these to your site's paths
            public const string CSS = "~/App_Themes/Third/";
            public const string JS = "~/js/";
        }
    
        public class Extensions
        {
            public const string CSS = ".css";
            public const string JS = ".js";
        }
    
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentEncoding = System.Text.Encoding.Default;
    
            context.Response.Cache.SetExpires(DateTime.Now.Add(CacheDuration));
            context.Response.Cache.SetMaxAge(CacheDuration);
            context.Response.Cache.SetCacheability(HttpCacheability.Private);
            context.Response.Cache.SetLastModified(DateTime.Now.AddMonths(-1));
    
            string cssFiles = context.Request.QueryString["css"];
            string jsFiles = context.Request.QueryString["js"];
            string fileName = context.Request.QueryString["f"];
    
            if (!string.IsNullOrEmpty(cssFiles))
            {
                // A list of CSS files has been passed in, write each file's contents to the response object
                context.Response.ContentType = ContentTypes.CSS;
                foreach (string cssFile in cssFiles.Split(DELIMITER))
                {
                    WriteCompressedFile(context, cssFile + Extensions.CSS, Folders.CSS);
                }
            }
            else if (!string.IsNullOrEmpty(jsFiles))
            {
                // A list of JS files has been passed in, write each file's contents to the response object
                context.Response.ContentType = ContentTypes.JS;
                foreach (string jsFile in jsFiles.Split(DELIMITER))
                {
                    WriteCompressedFile(context, jsFile + Extensions.JS, Folders.JS);
                }
            }
            else if (!string.IsNullOrEmpty(fileName))
            {
                // A specific file has been passed in, write that file's contents to the response object
                if (fileName.EndsWith(Extensions.JS))
                {
                    context.Response.ContentType = ContentTypes.JS;
                    WriteCompressedFile(context, fileName, Folders.JS);
                }
                else if (fileName.EndsWith(Extensions.CSS))
                {
                    context.Response.ContentType = ContentTypes.CSS;
                    WriteCompressedFile(context, fileName, Folders.CSS);
                }
                else
                {
                    // 500?
                    //Throw New System.IO.FileNotFoundException("The file specified isn't an allowed type.", fileName)
                    context.Response.ContentType = ContentTypes.ERROR;
                }
            }
            else
            {
                // 404?
                //Throw New System.IO.FileNotFoundException("A filename hasn't been specified.")
                context.Response.ContentType = ContentTypes.ERROR;
                context.Response.Write(Environment.NewLine);
            }
    
            // compress output if enabled
            if (ENABLEHTTPCOMPRESSION)
            {
                string encodingsAccepted = context.Request.Headers["Accept-Encoding"];
                if (!string.IsNullOrEmpty(encodingsAccepted))
                {
                    encodingsAccepted = encodingsAccepted.ToLowerInvariant();
                    if (encodingsAccepted.Contains("deflate"))
                    {
                        context.Response.AppendHeader("Content-Encoding", "deflate");
                        context.Response.Filter = new System.IO.Compression.DeflateStream(context.Response.Filter, System.IO.Compression.CompressionMode.Compress);
                    }
                    else if (encodingsAccepted.Contains("gzip"))
                    {
                        context.Response.AppendHeader("Content-Encoding", "gzip");
                        context.Response.Filter = new System.IO.Compression.GZipStream(context.Response.Filter, System.IO.Compression.CompressionMode.Compress);
                    }
                }
            }
        }
    
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    
        public void WriteCompressedFile(HttpContext context, string fileName, string folder)
        {
            // Add each file's compressed contents to the cache as it is read with a file dependency on itself
            if (context.Cache[fileName] == null)
            {
                string filePath = HttpContext.Current.Server.MapPath(folder + fileName);
                string output = string.Empty;
                try
                {
                    output = System.IO.File.ReadAllText(filePath);
                    if (folder == Folders.JS)
                    {
                        output = Yahoo.Yui.Compressor.JavaScriptCompressor.Compress(output) + Environment.NewLine;
                    }
                    else
                    {
                        output = Yahoo.Yui.Compressor.CssCompressor.Compress(output) + Environment.NewLine;
                    }
                    context.Response.Write(output);
                    context.Cache.Insert(fileName, output, new System.Web.Caching.CacheDependency(filePath));
                }
                catch (System.IO.FileNotFoundException)
                {
                    // throw 404?
                }
            }
            else
            {
                context.Response.Write((string)context.Cache[fileName]);
            }
        }
    

     

    Example of using: 

    /handlers/compressor.ashx?js=jquery-1.7.1.min,jquery.lazyload.min,jquery.cycle.min,jqModal,jquery-ui-1.8.18.custom.min,modernizr.custom

     

    Thanks,

    Alexandr

  • Ivan 165 posts 543 karma points
    Oct 23, 2012 @ 15:07
    Ivan
    1

    Hi again, guys.

    The ClientDependency thing works ok for me, thanks.

    PS.

    Alexander, glad to hear from you here on this forum ;) Cheers!

Please Sign in or register to post replies

Write your reply to:

Draft