Mar 11, 2008

CSS Minifier : A simplified and performant version

Today I happened to read about a CSS minimization solution here.  While it does the job well, there is a big problem... the solution ends up creating way too many temporary strings.  Given the fact that the input CSS string would be typically of the order of 10kb, avoiding the temporary strings would make a difference.  I have been using a CSS minimizer in my project over a year now and thought of sharing it with you.  I'm not sure whether it handles all possible scenarios but it has been working well for me...

// helper class to minify CSS
public static class CSSCruncher
{
//regex to identify flab in the CSS
private static Regex _cssCruncher = new Regex(@"(?<comment>\s*/[*](([^*]*)|([*]+[^*/]))*[*]/\s*)|(\s*(?<token>\{|\}|:|;|,)\s*)|(?<trim>(\A\s+|\z\s+))", RegexOptions.Compiled);

//utility to minify the CSS
public static string GetCrunchedCss(string cssContent)
{
return _cssCruncher.Replace(cssContent, delegate(Match m)
{
// default replacement string is String.Empty
string replacement = String.Empty;

// if the captured group is a token group when replacement string is the token value
if (m.Groups["token"].Success)
{
replacement = m.Groups["token"].Value;
}

return replacement;
});
}
}



The <comment> group in the reg-ex captures the multi-line comments with starting and trailing whitespaces.  The <token> group captures special tokens in CSS like {, }, :, ; and comma with starting and trailing white-spaces.  The <trim> group captures whitespaces at the start and end of the string.  The replacer-delegate replaces the <comment> and <trim> groups with empty string and the <token> group with only the token value without the white-spaces.



Hope you find it useful.



Update: Upon running a benchmark of this solution against the solution by Zack, to my surprise, I found that Zack's solution performs faster.  Seems that the way in which the reg-ex in my solution is organized is the culprit.  Modifying it a bit improves the speed but I'm going to leave it as it is and point you to Zack for your CSS minifier. :-)




kick it on DotNetKicks.com

1 comments:

Zack Owens said...

Very nice. I don't completely agree with your disageement of my solution, but that's ok ;) The performance wouldn't be that much greater (since strings are practially the most performant thing in the CLR)... but I'll try it out and let you know.

Zack