Techniques Behind Modern Web
10 Mar
A few weeks ago, I posted a comparison of Dojo ShrinkSafe, YUI Compressor and Jasob Obfuscator. Then, I received comment from Brian introducing an interesting project: Include; some day later it was covered by Ajaxian with a few good comments that are worth a read. So, I decided to integrate into one of my projects to have hand-on experience with the lib.

Briefly, my project is a full-Ajax application based on Ext JS lib. I try to separate all parts of the app as independent modules, so you can see all JavaScript files called in development mode as follows:
1 2 3 4 5 6 7 8 | <script src="scripts/sha1-min.js" type="text/javascript"></script> <script src="scripts/ext-base.js" type="text/javascript"></script> <script src="scripts/ext-all.js" type="text/javascript"></script> <script src="scripts/fr_common.js" type="text/javascript"></script> <script src="scripts/fr_feedsnap.js" type="text/javascript"></script> <script src="scripts/fr_mod_save.js" type="text/javascript"></script> <script src="scripts/fr_mod_feedreader.js" type="text/javascript"></script> <script src="scripts/fr_viewer.js" type="text/javascript"></script> |
In production, I use Ant scripts to concat all application JS files together then compress them using YUICompressor. One more step is to combine Ext JS lib with the application scripts to reduce calls to server utilizing a nice solution by Niels Leenheer. See final script:
1 | <script type="text/javascript" src="scripts/combine.php?type=javascript&files=sha1-min.js,ext-base.js,ext-all.js,feedready-min.js"</script> |
It works like charm and I can see all scripts loaded in Firebug console: 152 KB total after gzipped.
![]()
Using “Include” I can load all above JS files all with a 2 scripts:
1 2 3 4 5 | <script src="scripts/include.js" type="text/javascript"></script> <script type="text/javascript"> include.setup({env: 'compress'}); include('scripts/sha1-min', 'scripts/ext-base', 'scripts/ext-all','scripts/fr_common', 'scripts/fr_feedsnap', 'scripts/fr_mod_save', 'scripts/fr_mod_feedreader', 'scripts/fr_viewer'); </script> |
Watching how script files are loaded, I find no real benefit but a few extra loads of “Include” itself.

However, it’s interesting that a popup window appears showing all JS files are being compressed. You can see compression progress, how all files are combined and the compressed scripts for using in production (see image below).

Now, just copy compressed scripts to “production.js” file, put the file into source directory and replace the above “Include” scripts with the following snippet:
1 2 3 4 | <script src="scripts/include.js" type="text/javascript"></script> <script type="text/javascript"> include('scripts/production'); </script> |
Press F5 to re-load the app; I can see the “production.js” file loaded, only 151 KB total (after gzipped).

First, though all scripts seemed to be loaded properly, my app didn’t work as expected in production. Firebug reported a few errors of missing “;” mark - some I can fix, some I’m still unable to identify why.

Second, I could not switch to “Production” by just setting environment variable like:
1 | include.setup({env: 'production'}); |
Default script directory of my app is “Scripts” instead of “Javascript“. I’ll ask Brian for configuration guide.
“Include” is great idea to get rid of all server-side compression hacks. It has the ability to load conditional plugins in logical way (FILO) that I find I can take advantage of in my projects.
Problem is Dean Edwards’ Packer used for compression did not produce “safe” scripts for my project but I think I hadn’t put enough time to get the cause to fix. Hopefully, I can update with more positive result later.
Sponsored by Free Website Trade Publication >> Website Magazine
Don't forget to subscribe
so you don't miss out on future posts!
Problem is Dean Edwards’ Packer used for compression did not produce “safe” scripts for my project…
so switch to MyMin from packed.it![]()
It is true that Packer requires correct semi-colon usage in all your scripts for the compressed code to work correctly. I’ve found the best way to fix problems is to narrow down missing semicolon problems is like this:
1) compress the problem script in packer directly (http://dean.edwards.name/packer/)
2) put the compressed script in eclipse (my IDE of choice)
3) if eclipse shows a syntax error, cut the code in half and try both halfs until the problem is found
Alternatively, YUI Compressor doesn’t have the same strict requirements for syntax. We’ve written a Ruby server-side script that works by accepting the ordered list of files generated by Include and using YUI Compressor on the files. More info on that (and the download) is on the main Include page (http://javascriptmvc.com/learningcenter/include/index.html), or in this readme: http://javascriptmvc.com/include_ruby/readme.txt
If you need to change the default location of your production file, you can do so like this:
include.setup({env: ‘production’, production: ’scripts/production.js’});
Doing this will also remove those extra loads of include you’re seeing in Firebug because you’ll be using production mode. Check out the API docs for more info (http://javascriptmvc.com/learningcenter/include/api.html).
@Andrea, I will look into the MyMin compressor. If it is written in JavaScript and relaxes the syntax requirements of Packer, you may see it in a future release.
- Brian
Close Look into “Include” JavaScript Compression Lib - A Client-Side Solution | Just Talk About Web…