Javascript – Guidelines for HTML/CSS/JS optimization process

csshtmljavascriptoptimizationweb-development

Currently we have a Development server on which we write the HTML/CSS/JS code. We do not optimize our code using compressors/minifiers. So our deployment process from Development to Production is simply to copy the files on the Development server to the Production server.

But now we are planning to use compressors/minifiers. We are confused about the process we should follow. Currently we use a single JS file called common.js and a single CSS file called common.css. Also now we are planning to use multiple CSS files in Dev like reset.css, common.css, etc. and when deploying them to production we will be combining them to a single CSS file.

The simplest process I can think of is:

  1. Make an exact copy of the development files on the Development server. Use the copy in the further steps.
  2. Combine all CSS files to a single CSS file say common.css. Same with JS files. Delete the other files for example reset.css.
  3. Compress/minify common.css and common.js to common.min.css and common.min.js.
    Delete common.css and common.js.
  4. In all the HTML files remove all link tags and script tags except for common.css and common.js
  5. In all the HTML files modify the script src and link href from common.js to common.min.js and common.css to common.min.css.
  6. Copy all the files to Production server.
  7. Delete the copy

This looks too tedious for us. What can be a better process? Is there any tool which can do the optimization (above steps) automatically. It looks like it would not be very difficult to write a script which performs all of the above steps. But I would like to use an existing tool rather than developing one myself. I would like to put the efforts only if such a tool does not exist.

Also when is the testing generally performed? I think it should be performed on the optimized files (just in case the compressors have some bug). But then the process would become more tedious as the above process would have to be repeated after every Test-Bugfix cycle.

Best Answer

I worked on a project which were very close to your situation. The requirements were the following:

  1. On development side, each page can have one or several JavaScript files and one or several CSS files. All those files are local.
  2. In production, there must be one and one only JavaScript file and one and one only CSS file. Those two files are hosted on a distant server, optimized for static files and configured for client and server side caching.
  3. Each page has a link to JQuery hosted at Google CDN in both development and production environments.
  4. The deployment process must be automated.
  5. The deployment process must not modify files other than JavaScript and CSS files for compression.
  6. The website is written in ASP.NET.
  7. Every page of the website uses the same CSS and the same JavaScript.
  8. On development side, CSS and JavaScript files are always in a specific predefined directory.

Here what was done by my colleague who worked on this part of the project.

  1. All files except JQuery are minified and combined into two files: g.css and g.js, g for global. This is simply done by walking though the specific directory and searching for those files. After minifying them, the two files are send to the static content server, if they were changed since the last deployment.
  2. The process is executed at every build, since we couldn't find how to execute it at deployment only. It doesn't matter, after all, since it takes a few milliseconds to walk through all files and check if they were modified since the last build.
  3. The website is deployed as is, except the original JavaScript and CSS files. We don't need them in production.
  4. The masterpage (in ASP.NET) contains a specific method which is adjusting the calls to the JavaScript and CSS files depending of the context.

This method is like this:

public string MakeCssCalls(IList<string> cssFiles)
{
    // ...
}

In development environment, it returned the links to CSS files inside the cssFiles argument. In production, it ignored this argument and just returned "<link rel="stylesheet" href="http://static.example.com/g.css" type="text/css" />". It made the difference between production and development by comparing the machine name to the list of names in Web.config file: some machines were configured as being development machines; all machines outside this list were assumed production servers.


Performance-wise, it would be smarter to have a different Web.config file for production, indicating that we are actually in production (and, for example, precising the exact link to the static server with those files; in our case it was hardcoded, and that sucks). We couldn't do it this way because one of the requirements of this project was to have a single Web.config file for all environments, but if you can, do it.


Also when is the testing generally performed? I think it should be performed on the optimized files (just in case the compressors have some bug).

We tested the website on non-minified versions of files. We never had any bug coming from Google Closure (nor our home-made crappy CSS minifier).