Tuesday, April 6, 2010

Combine multiple css files into one file and minify css and javacript using NAnt

You can also see my code project article Combine Multiple css Files into One File and Minify css and javascipt using Nant
When you use multiple css files in project , for each css file it makes extra HTTP request to server. Even though you use ASP.NET theme it breaks out into multiple css files. Also if you minimize the size of css files then your page will load faster.
In development time you might want to organize css into multiple files and with proper whitespace and comments. But you should keep in mind that Internet Explorer 6, 7 do not support more than 31 css files in a single page. In case of deployment you can combine multiple css files into single css file and also minimize size of file using minifier like YUI compressor for loading your page faster.
ASP.NET theme is used in our application so if I replace multiple css files into one css it does not affect application wide. You can also combine javascript files into one file. But in our application javascript files have direct references in user controls so I have only minified javascripts files in deployment. You can combine multiple javascript files into one using composite script references the Script Manager Combining Client Scripts into a Composite Script. Here I will discussion only deployment time process which help to load your page faster.
For automating all these process I used NAnt tool. Combining multiple files into one file is easy in NAnt using task. Also for minifying css and javascript files I used YUI compressor.
First I discuss process steps before going to example:
  • combine all css files into one files. NAnt give you a easy way to do this using task.
  • After combining multiple css files and javascript files are minified using YUI compressor. YUI compressor safely minimizes your css and javacript file size.
  • Add created single css file in project and remove other unused css files from project reference. So that It does not break your setup and after deployment you get only one compressed css files.
Here I have given code block which combine multiple css files into single style.css files and delete other css files from Theme folder.
you need to have NAnt contrib dll registered or you can add <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />.


<target name="css" description="Concatenate CSS source files">
<loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />
<echo message="Building ${BuildDir}\${CssFileLocation}\style.css" />
<concat destfile="${BuildDir}\${CssFileLocation}\style.css" append="true">
<fileset>
<include name="${BuildDir}\${CssFileLocation}\*.css" />
</fileset>
</concat>
<echo message="${BuildDir}\${CssFileLocation}\style.css built." />
<echo message="delete other files except style.css" />
<delete>
<fileset>
<include name="${BuildDir}\${CssFileLocation}\*.css"/>
<exclude name="${BuildDir}\${CssFileLocation}\style.css"/>
</fileset>
</delete>
<echo message="delete other files except style.css is done" />

</target>

For minimizing the size of css files and javascipts files I used YUI compressor. The article YUI Compressor and NAnt have nice script for minifying css and javascript using Nant.

I have removed css files from theme folder but references of these files exist in my web project. In NAnt I run a C# code block which work before I build my solution. This code first finds all references of css files in web project and then removes these references and also adds new style.css reference.


<target name="ReplaceCss">
<property name="filename" value="${BuildDir}\${WebProjectPath}" />
<script language="C#">
<code>
<![CDATA[

public static void ScriptMain(Project project)
{
StreamReader projectFileReader = new StreamReader(project.Properties["filename"]);

string replacement =  @"<Content Include=\""App_Themes\\ABC\\[\w-]+.css\"" />";
string fileversionreplacement = @"<Content Include='App_Themes\ABC\style.css'/>";   
string x = @"<Content Include=\""App_Themes\\ABC\\[\w-]+.css\"" />";          
string output = @"<Content Include='App_Themes\ABC\style.css'/>";
Regex sourcePathRegx = new Regex(x);
string projectFile;
try
{
projectFile = projectFileReader.ReadToEnd();
}
finally
{
projectFileReader.Close();
}
MatchCollection match = sourcePathRegx.Matches(projectFile);
if(match.Count>0)
{
int i = 0;
foreach (Match collection in match)
{
if(i==0)
{
projectFile = projectFile.Replace(collection.Value, output);
}
else
{
projectFile = projectFile.Replace(collection.Value, string.Empty);
}
i++;
}                
}
StreamWriter projectFileWriter = new StreamWriter(project.Properties["filename"]);
try
{
projectFileWriter.Write(projectFile);
}
finally
{
projectFileWriter.Close();
}   
}
]]>
</code>
</script>
</target>


Another approach you can use in setup project by adding Exclude Filter where you can exclude redundant css files but for this you need to add style.css file in your web project.

No comments:

Post a Comment