TwitterFacebook

Minifying Javascript With the Google Closure Compiler API

Honey, I shrunk the codes
LGF • Views: 35,939
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
Randall Gross
San Diego Comic Con 2014 (SDCC) Cosplay Music Video
To celebrate us recently hitting 100,000 Subscribers & 100 videos make sure you watch to the end for a little give away competition. To enter you must tweet us who you would like to see Nathan Fillion & Adam ...

13 hours, 6 minutes ago
Views: 101 • Comments: 0
Tweets: 0 • Rating: 1
CriticalDragon1177
Skepchick - Food is for White Liberals What Sex Is For The Religious Right
An interesting commentary by Julia Burke, on the obsession some people on the far left have with food, and how it is similar to how some people on right feel about sex. Do you agree? Do you think the analogy ...

1 day, 17 hours ago
Views: 353 • Comments: 9
Tweets: 1 • Rating: 1
EiMitch
Cracked: 5 Reasons The Classic American Summer is Totally Dead
They could've called this article "Look at how 'supply-side' economics, anti-environmentalism, and all-around pro-oligarch legislation and ideology has destroyed some of the most iconic, classic Americana." cracked.com Oh, and gentrification-based laws are also robbing us of the classic ice-cream truck ...

1 day, 17 hours ago
Views: 234 • Comments: 0
Tweets: 0 • Rating: 1
_RememberTonyC
Qatar, Bergdahl, and Hamas
One thing we have learned in the current conflict is that Hamas has three main sponsors: Turkey, Iran, and Qatar. So when Bergdahl was released and the five taliban bigs were released into the "custody" of Qatar, we basically handed ...

2 days, 11 hours ago
Views: 205 • Comments: 1
Tweets: 0 • Rating: 0
Skip Intro
Outside Money Drives a Deluge of Political Ads
WASHINGTON -- An explosion of spending on political advertising on television -- set to break $2 billion in congressional races, with overall spots up nearly 70 percent since the 2010 midterm election -- is accelerating the rise of moneyed ...

3 days, 22 hours ago
Views: 236 • Comments: 1
Tweets: 4 • Rating: 3
Rightwingconspirator
Washington, D.C., Handgun Carry Ban Is Ruled Unconstitutional
I agree. Bans are not an option. Jurisdictions like DC will just have to deal with the fact that regulation is the path. Bans don't work. Bans are illegal and unwise. It's simple. we as a society have chosen to ...

4 days, 17 hours ago
Views: 567 • Comments: 95
Tweets: 1 • Rating: 6
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 ...

6 days, 19 hours ago
Views: 542 • Comments: 12
Tweets: 0 • Rating: 5
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 ...

1 week ago
Views: 434 • Comments: 2
Tweets: 0 • Rating: 1
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, ...

1 week, 2 days ago
Views: 298 • 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 ...

1 week, 4 days ago
Views: 487 • Comments: 0
Tweets: 1 • Rating: 1
 Frank says:

Here I stand hoping against hope that it's a chick with a low voice. -- At a concert in Beloit, Wisconsin 1968 or 69, when a guy in the audience yelled out, "Eat me Zappa".