TwitterFacebook

Minifying Javascript With the Google Closure Compiler API

Honey, I shrunk the codes
LGF • Views: 35,917
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.

^ back to top ^

TwitterFacebook

Turn off all ads for a full year by subscribing!
For about 33 cents a day (per month) or 22 cents a day (per year), our subscription option turns off all advertisements at LGF!
Read more...

► LGF Headlines

  • Loading...

► Tweeted Articles

  • Loading...

► Tweeted Pages

  • Loading...

► Top 10 Comments

  • Loading...

► Bottom Comments

  • Loading...

► Recent Comments

  • Loading...

► Tools/Info

► Tag Cloud

► Contact

You must have Javascript enabled to use the contact form.
Your email:

Subject:

Message:


Messages may be published unless you request otherwise.
Tech Note:
Using the Contact Form
LGF Pages

This button leads to the main index of LGF Pages, our user-submitted articles. You can post your own LGF Pages simply by registering a free account with us.

Create a Page

This 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: 2014-03-07 2:19 pm PST

LGF User's Guide
Recent Pages
Romantic Heretic
Preventing Poverty Not Allowed As A Goal for Charity
The Canada Revenue Agency (Canada's equivalent of the IRS) has told OXFAM Canada that it cannot list 'preventing poverty' as a goal, only 'alleviating' it. The reason is "Relieving poverty is charitable, but preventing it is not." This is just ...

5 hours, 6 minutes ago
Views: 78 • Comments: 0
Tweets: 0 • Rating: 0
Randall Gross
Corporations Are People. So What if People Were Corporations?
"Checked the tax code," wrote a friend who's engaged to a woman from a low-tax country. "Unfortunately, marrying [my fiancee] does not entitle me to a tax inversion like the big US companies are getting. Thanks for nothing IRS." ...

9 hours, 24 minutes ago
Views: 238 • Comments: 4
Tweets: 8 • Rating: 4
FemNaziBitch
Safer Era Tests Wisdom of ‘Broken Windows’ Focus on Minor Crime
While the apparent chokehold fueled much of the initial public outcry, community leaders have begun asking whether focusing police officers so intently on such petty offenses makes sense in a city that is far different and far safer than ...

12 hours, 10 minutes ago
Views: 125 • Comments: 1
Tweets: 0 • Rating: 0
Mentis Fugit
Frisson
Over at the quirky Riddled blog, I encountered this music video link. I have the album, but I had last listened long ago, and I had forgotten the lyrics. The lengthy, moody intro slowly drew me back thirty five years, ...

2 days, 21 hours ago
Views: 180 • Comments: 0
Tweets: 0 • Rating: 0
BadExampleMan
The painful futility of war
This makes me furious. These men pledged their loyalty to their country and their country betrayed them. It treated them as disposable, throwing their lives away in a war that was premised on lies, that was chosen gleefully, and that ...

4 days, 14 hours ago
Views: 343 • Comments: 0
Tweets: 1 • Rating: 1
MichaelJ
Mick Fanning Wins J-Bay Open 2014
More: MICK FANNING WINS J-BAY OPEN Finals day for the contest was run in perfect Supertubes conditions. Too bad Kelly Slater and Jordy Smith were eliminated in lesser quality surf - it would have been amazing to have both of ...

4 days, 23 hours ago
Views: 274 • Comments: 0
Tweets: 0 • Rating: 2
Rightwingconspirator
ISIS Threatens Iraqi Christians in Mosul
Baghdad, Iraq (CNN) -- Extremists occupying large swaths of Iraq and Syria have issued a threat to Iraqi Christians in the city of Mosul: accept Islam, pay extra taxes to Islamic Sharia courts or face "death by the sword." ...

1 week ago
Views: 701 • Comments: 9
Tweets: 20 • Rating: 3
Thrazidun
Paris: Jews Fight Back Against Islamist Mob - Jewish World - News - Arutz Sheva
More: Paris: Jews Fight Back Against Islamist Mob - Jewish World - News - Arutz Sheva

1 week ago
Views: 821 • Comments: 5
Tweets: 0 • Rating: 1
GlutenFreeJesus
Gotta love Chicago
Admittedly, I only started following these guys in the past year or two. They have been in the Chicago scene for awhile. And I kick myself after every show for not following them sooner. For any fans of Led Zeppelin, ...

1 week ago
Views: 372 • Comments: 0
Tweets: 0 • Rating: 2
wheat-dogghazi
Rachel Aviv: A Middle-School Cheating Scandal Raises Questions About No Child Left Behind
Writing for The New Yorker, Rachel Aviv profiles some of the teachers and principals caught up in Atlanta's standardized cheating scandal. Focusing on Parks Middle School, which is located in a "rough" section of the city, her article portrays a ...

1 week ago
Views: 577 • Comments: 2
Tweets: 8 • Rating: 2
 Frank says:

Bring the band on down behind me, boys.