How to Optimize JavaScript and CSS in Linux Using the YUI Compressor

There are many guidelines for speeding up your site. In this tutorial, written for the Linux operating system, we focus only on optimizing JavaScript and CSS files. We will do this by minimizing and combining the files using Yahoo's YUI Compressor.

Previous research showed that a browser spends between 62% to 95% of the time making HTTP requests to gather all the necessary elements needed to render the HTML page, other than the HTML page itself. We will reduce the number of HTTP requests by combining all JavaScript files into a single file and all CSS files into another file. We also make sure that the resulting files have the minimum possible size without losing any information.

In other words, in our HTML page, instead of ten external scripts and css files:

<html>
  <head>
    <link rel="stylesheet" href="css/jquery-fancybox.css" type="text/css" />
    <link rel="stylesheet" href="css/jquery-ui.css" type="text/css" />
    <link rel="stylesheet" href="css/site.css" type="text/css" />
    <script type="text/javascript" src="js/jquery-1.4.4.js"></script>
    <script type="text/javascript" src="js/jquery.easing-1.3.pack.js"></script>
    <script type="text/javascript" src="js/jquery.mousewheel-3.0.4.pack.js"></script>
    <script type="text/javascript" src="js/jquery.fancybox-1.3.4.pack.js"></script>
    <script type="text/javascript" src="js/jquery.ui.core.min.js"></script>
    <script type="text/javascript" src="js/jquery.ui.widget.min.js"></script>
    <script type="text/javascript" src="js/jquery.ui.accordion.min.js"></script>
  </head>
  <body>
  ...
  </body>
</html>

we want to include just two:

<html>
  <head>
    <link rel="stylesheet" href="css/all-css-min.css" type="text/css" />
    <script type="text/javascript" src="js/all-js-min.js"></script>
  </head>
  <body>
  ...
  </body>
</html>

In order to follow this tutorial you will need to have a Java Runtime Environment (JRE) installed, since the YUI Compressor is written in Java. It's also useful to have Bash for some scripting that can make our life a little bit easier.

In Ubuntu, you can install a JRE with the following command:

sudo apt-get install default-jre

Before we go deeper, it's worth mentioning that there are several places online where you can use the YUI Compressor to compress all your JavaScript and CSS files. Just google and pick the one you prefer. If this works for you then it's great. You can use one of those sites to compress your files one by one and then manually join them into a big file. It can be enough if your files are static and you rarely have to do this operation. But if you are like me then you might update your files pretty often and preparing them manually each time is time consuming and prone to errors.

To get started you first need to download the YUI Compressor. This tutorial refers to the latest available version, 2.4.2. After you download it, you must unzip it to the directory of your choice. I use /usr/local for my destination (thus the use of sudo), but you can use any path you want; just update the scripts accordingly. In a terminal, type:

sudo unzip ~/Downloads/yuicompressor-2.4.2.zip -d /usr/local
sudo ln -s /usr/local/yuicompressor-2.4.2 /usr/local/yuicompressor

We can now invoke the compressor:

java -jar /usr/local/yuicompressor/build/yuicompressor-*.jar

If everything works well you should see a list with the available parameters of the tool.

Usage: java -jar yuicompressor-x.y.z.jar [options] [input file]

Global Options
  -h, --help                Displays this information
  --type <js|css>           Specifies the type of the input file
  --charset <charset>       Read the input file using <charset>
  --line-break <column>     Insert a line break after the specified column number
  -v, --verbose             Display informational messages and warnings
  -o <file>                 Place the output into <file>. Defaults to stdout.

JavaScript Options
  --nomunge                 Minify only, do not obfuscate
  --preserve-semi           Preserve all semicolons
  --disable-optimizations   Disable all micro optimizations

If no input file is specified, it defaults to stdin. In this case, the 'type'
option is required. Otherwise, the 'type' option is required only if the input
file extension is neither 'js' nor 'css'.

We'll just wrap the YUI Compressor in a script so that we can compress and concatenate multiple files at the same time, without having to worry about running a correct Java command. It will also save us some typing later. You can download the script and save it as /usr/local/bin/yuicompress, or you can create it by hand. First open a text editor:

sudo pico /usr/local/bin/yuicompress

then copy and paste the code below, and finally save the file using CTRL-X.

#!/bin/bash
#/usr/local/bin/yuicompress
 
# the path to your java program to use
JAVA=java
 
# the location where YUI Compressor is installed
YUI=/usr/local/yuicompressor/build/yuicompressor-*.jar
 
# the maximum number of columns in the output files
COLS=4000
 
###############################################################################
 
outfile=
minimize=0
silent=
 
# read the options
while [[ "$1" == -* ]]; do
  if [ "$1" = -f ]; then
    minimize=1
    shift
  elif [ "$1" = -s ]; then
    silent=1
    shift
  elif [ "$1" = -o ]; then
    shift
    outfile=$1
    shift
  else
    echo Unknown option: $1
    exit 1
  fi  
done
 
if [ $# -lt 1 ]
then
  echo '
Usage: yuicompress [-o out] [-f] [-s] file1 file2 ...
 
Uses YUI Compressor to minimize multiple JavaScript or CSS files and
concatenate them into a single file. The files are concatenated in the
order they are received as parameters. The type of the input file is
determined by its extension: .js for JavaScript and .css for CSS. 
You cannot mix .js and .css files in the same command.
 
The output file is specified using -o followed by its name. If no 
output file is specified, the minimized content is printed to the 
standard output.
 
You can force the processing using -f. Without -f, the minimization 
is performed only if at least one input file is newer than the output 
file. If no output file is specified with -o, then -f is implicitly 
assumed.
 
Silent mode can be specified with the -s option. In this case all
progress output will be suppressed.
 
'
  exit 1
fi
 
if [ -z "$outfile" -o ! -e "$outfile" ]; then
  minimize=1
fi
 
# if not forced, minimize only if there is any newer input file
if [ $minimize != 1 ]; then
  for file in "$@"; do
    if [ "$file" -nt "$outfile" ]; then
      minimize=1
      break
    fi
  done
fi
 
# process one file at a time
if [ $minimize = 1 ]; then
  if [ -n "$outfile" ]; then
    rm -f "$outfile"
    test -z $silent && echo Output: $outfile
    for file in "$@"; do
      test -z $silent && echo Minimize "$file"... >&2
      "$JAVA" -jar $YUI "$file" --line-break $COLS >>"$outfile"
    done
  else
    test -z $silent && echo Output: standard output
    for file in "$@"; do
      test -z $silent && echo Minimize "$file"... >&2
      "$JAVA" -jar $YUI "$file" --line-break $COLS
    done
  fi
else
  test -z $silent && echo No newer file. Skipping... >&2
fi

It might be a good idea to also make this script executable. In a terminal, type:

sudo chmod +x /usr/local/bin/yuicompress

Now we can simply call the YUI Compressor by running the command yuicompress. To compress all the JavaScript and CSS files that were shown in the beginning, we run the following commands:

# cd /path/to/your/site/code

yuicompress -o css/all-css-min.css css/jquery-fancybox.css css/jquery-ui.css css/site.css

yuicompress -o js/all-js-min.css js/jquery-1.4.4.js js/jquery.easing-1.3.pack.js \
  js/jquery.mousewheel-3.0.4.pack.js js/jquery.fancybox-1.3.4.pack.js \
  js/jquery.ui.core.min.js js/jquery.ui.widget.min.js js/jquery.ui.accordion.min.js

This has been very helpful for me, since I am editing most of my sites locally and then uploading the code to the live website with rsync. Before running rsync I compress the JavaScript and CSS files with the yuicompress command shown above. I use rsync to only update changed files, so it helps that yuicompress creates a new file only if some of the original files were changed.

If you want to understand how the YUI Compressor manages to reduce the size of the JavaScript and CSS files without losing any information, you should check the YUI Compressor page.

 

If you enjoyed this article, you might also be interested in:

RSSSubscribe to our blog to follow our tutorials and news updates.

We offer web design and development services to small businesses, non-profits and individuals. Check out our work and get a free, no-obligation quote!