Minifying Javascript With the Google Closure Compiler API

Honey, I shrunk the codes
LGF • Views: 41,944
Javascript via Shutterstock

The dirty secret of these tech posts is that I often write them for myself, because they help me organize my thoughts; sometimes the process of making it simple enough and abstract enough to post about on LGF even suggests improvements to programming techniques.

And believe it or not I got an email today from someone saying they wished I’d do more of them. So that’s pretty much all the excuse I need to launch into another tech/programming article that can be treated as an open thread by the non-programmers amongst us.

A while back I wrote an article titled Tech Note: Minifying Javascript Quickly and Easily, about the method I used to compress and “minify” our Javascript files before sending them out over the interwebs.

This method has evolved quite a bit, and now LGF uses the Google Closure Compiler to perform this compression, because it does a vastly better job than the outdated minifier we were using, and also has some simple syntax checking.

If the old minifier failed in some way, it used to happily create a bad Javascript file, and you found out when you loaded the page and there was no Javascript working at all. The Closure Compiler exits gracefully with an error, a line number, and a useful message about why it failed.

There are several ways to use the Closure Compiler — as a simple web application, as a Java application that you install on a server, or as a web API using the REST protocol. This bit of nerd doggerel I’m about to foist on you shows how to use the RESTful API to generate a minified version of one Javascript file, with a Linux bash script that you execute on your server after making changes to the Javascript code.

This code sends the web URL of a Javascript file to the Closure compiler, then saves the returned minified code on your server and moves it into place with a safe rename command, so no one gets caught loading it in mid-change.

The paths and filenames are generalized here — if you use the code, fill in the proper values, then save it wherever you put your bash scripts and give it executable permissions. I use the command name lgfj for our version at LGF, to make typing easy.

To start with, we set the working directory to the path where our Javascript files are located and print out a warm, fuzzy welcome message.

#!/bin/bash

cd /path/to/javascript/files/

echo -e "\nJavascript Minifier (API version)\n"
echo "Minifying test.js with Closure Compiler..."

In order to pass the web address of a Javascript file to the Closure Compiler’s API, we need to “URL-encode” it, which means to replace some characters with special codes. We’ll use Perl’s URI::Escape module for this.

And there’s a lurking gotcha that I discovered when first working with this script: Google’s API can’t always tell when you’ve changed the code, and will use a cached version to speed things up. Since we’re only running this after we’ve made a change, we never want this behavior. So we use a simple method to force Google not to cache the file: we append the Linux date value to the Javascript file’s URL as a query string. Since this value increases every second, it changes every time we use it — so our Javascript file will always look like a different file to Google.

All this happens in the following somewhat gnarly looking line of code. The result is stored in the variable $URL.

URL=$(echo "http://yourdomain.com/js/test.js?"$(date +%s) | perl -MURI::Escape -lne 'print uri_escape($_)')

OK, now we do the actual deed and call the Closure Compiler’s API, by using Linux’s curl command with the -d flag that tells it to use the POST method. See the docs for more info on the parameters in the query string.

The resulting minified code is then written out to the file test.min.tmp.js.

curl -d "output_info=compiled_code&output_format=text&compilation_level=SIMPLE_OPTIMIZATIONS&code_url=$URL" 'http://closure-compiler.appspot.com/compile' > test.min.tmp.js

Now we set the file’s owner to whatever is appropriate, and safely move the minified file into place by renaming test.min.tmp.js to test.min.js.

echo "Creating lgf.min.js..."

chown username test.min.tmp.js
mv -f test.min.tmp.js test.min.js

echo "Completed."

Done! But let’s also share some information about what just happened. These concluding lines show the file sizes of the original Javascript file and the minified version, and the amount saved by the minification process.

OSIZE=$(stat -c%s test.js)
MSIZE=$(stat -c%s test.min.js)
echo -e "Original size: "$(printf "%'d\n" $OSIZE)" bytes"
echo -e "Minified size: "$(printf "%'d\n" $MSIZE)" bytes"
echo -e "Saved:         "$(printf "%'d\n" $(($OSIZE - $MSIZE)))" bytes\n"

Here’s the whole thing in one piece:

#!/bin/bash

cd /path/to/javascript/files/

echo -e "\nJavascript Minifier (API version)\n"
echo "Minifying test.js with Closure Compiler..."

URL=$(echo "http://yourdomain.com/js/test.js?"$(date +%s) | perl -MURI::Escape -lne 'print uri_escape($_)')

curl -d "output_info=compiled_code&output_format=text&compilation_level=SIMPLE_OPTIMIZATIONS&code_url=$URL" 'http://closure-compiler.appspot.com/compile' > test.min.tmp.js

echo "Creating lgf.min.js..."

chown username test.min.tmp.js
mv -f test.min.tmp.js test.min.js

echo "Completed."

OSIZE=$(stat -c%s test.js)
MSIZE=$(stat -c%s test.min.js)
echo -e "Original size: "$(printf "%'d\n" $OSIZE)" bytes"
echo -e "Minified size: "$(printf "%'d\n" $MSIZE)" bytes"
echo -e "Saved:         "$(printf "%'d\n" $(($OSIZE - $MSIZE)))" bytes\n"

You can also use the Closure Compiler API to compress and combine a series of Javascript files into one big file, which can save even more loading time, but that’s a subject for another nerdy nerd thread.

Jump to top

Create a PageThis is the LGF Pages posting bookmarklet. To use it, drag this button to your browser's bookmark bar, and title it 'LGF Pages' (or whatever you like). Then browse to a site you want to post, select some text on the page to use for a quote, click the bookmarklet, and the Pages posting window will appear with the title, text, and any embedded video or audio files already filled in, ready to go.
Or... you can just click this button to open the Pages posting window right away.
Last updated: 2023-04-04 11:11 am PDT
LGF User's Guide RSS Feeds

Help support Little Green Footballs!

Subscribe now for ad-free access!Register and sign in to a free LGF account before subscribing, and your ad-free access will be automatically enabled.

Donate with
PayPal
Cash.app
Recent PagesClick to refresh
Once Praised, the Settlement to Help Sickened BP Oil Spill Workers Leaves Most With Nearly Nothing When a deadly explosion destroyed BP’s Deepwater Horizon drilling rig in the Gulf of Mexico, 134 million gallons of crude erupted into the sea over the next three months — and tens of thousands of ordinary people were hired ...
Cheechako
Yesterday
Views: 69 • Comments: 0 • Rating: 0
Texas County at Center of Border Fight Is Overwhelmed by Migrant Deaths EAGLE PASS, Tex. - The undertaker lighted a cigarette and held it between his latex-gloved fingers as he stood over the bloated body bag lying in the bed of his battered pickup truck. The woman had been fished out ...
Cheechako
4 days ago
Views: 169 • Comments: 0 • Rating: 1