Optimising CSS and Javascript during the build process

If you are a web developer who cares about your site's performance then take a look at YSlow. YSlow is an information rich firefox plugin that analyses a site and suggests performance improvements based on Yahoo research.

When I analysed my current project with YSlow its number one recommendation was to reduce the number of Http requests. The site uses a lot of javascript so it imports over a dozen js files. If you have a large site and want to organise your css well then you will end up with a similar number of CSS files.

To improve the sites performance I added two new steps to the build process:

  • concatenate script files
  • minify script files

Concatenate Script Files

Different pages need different combinations of script files. I organised my scripts into folders that reflect the groupings in which they are needed. In the build process I want to loop through the script folders and for each folder produce a single js file that is the concatenation of all of the js files in that folder. By concatenating all of the script files required by a page I can theoretically reduce the number of http requests for js files to 1 per page. This example uses NAnt and NAnt contrib.

<target name="concatJavascript">
    <foreach item="Folder" in="${web.dir}\Content\Scripts" property="foldername" >
      <ifnot test="${string::ends-with(foldername, '.svn')}">
          <concat destfile="${foldername}_concat.js" unless="${string::ends-with(foldername, '.svn')}">
            <fileset>
              <include name="${foldername}\*.js" />
            </fileset>
          </concat>
      </ifnot>
    </foreach>    
  </target>

Minify Script Files

Having produced the minimum required number of js files the build process then loops over the files and minifies them, using packer and jsmin.

<target name="minifyJavascript" depends="concatJavascript">
    <foreach item="File" in="${web.dir}\Content\Scripts" property="filename">     
      <exec program="${packer.exe}" commandline="-o ${output.dir}\web\Content\Scripts\${path::get-file-name(filename)} -m jsmin ${filename}" />      
    </foreach> 
</target>

The end result is the minimum number of javascript files, all shrunk with jsmin. The same strategy could easily be applied to CSS files using the YUI compresser. Because the number of http requests has been reduced the pages now load noticeably faster. Because the work is done during the build process my development environment is not affected. I can have as many javascript files as I like, safe in the knowledge that it will not impact upon performance when the application is deployed.

 

UPDATE: enabling gzip compression on the server is another technique that can really help. In IIS 7 it is enabled by default for static content but it also a good idea to enable gzip for dynamic content.


Comments

Comments are closed