0

Problem: WAY too many javascript files. Solution: cf_scriptalizer

ColdFusion, Internet, Web Development, Javascript

We all know JQuery is awesome right? That should be common knowledge by now. But, if you have ever created an app that makes use of several of the fantastic plugins available for JQuery, then you are going to end up with multiple tags for JQuery alone...not to mention any of your own external javascript files.

So, why is this a problem?

First of all, there is a little bit of bloat going on in this scenario. One could easily end up with over 200Kb of javascript in an assortment of these files. The other thing to consider is that the browser can only make so many concurrent connections to the web server (each external javascript file is one connection by the way) so add all of these files, a bunch of images, a couple .css files and we are making that user wait longer than really necessary.

Lets reduce the number of browser - to - server connections.

That seems easy enough. Instead of multiple external script calls:

<script type="text/javascript" src="/js/jquery/jquery.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.form.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.jqModal.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.history_remote.pack.js"></script>

We could combine them all into one big javascript file and reference it:

<script type="text/javascript" src="/js/myBigScript.js"></script>

Well what happens when you want to make a change to one of the source js files? Or you need to change the order of how the files are included? Or maybe the javascript files needed vary based off of where you are in your app and you don't want to include ALL of the files every time? Thats where I think I can help...

I have just recently (as in today) finished up a custom tag to do just that. For lack of a better name I called it <cf_scriptalizer> Here is an example use of the custom tag.

<cf_scriptalizer 
	filePrefix="myscript"
		
	scriptalizerDirectory="/js" 
	
	scriptFileList="
		/js/jquery/jqModal.js,
		/js/jquery/jquery.js,
		/js/jquery/jquery.MultiFile.js,
		/js/jquery/jquery.blockUI.js,
		/js/jquery/jquery.corner.js,
		/js/jquery/jquery.form.js,
		/js/jquery/jquery.history_remote.pack.js,
		/js/jquery/jquery-dom.js
		"

	reload="true"
	>

  • filePrefix (optional): prefix of the generated javascript file. "scriptalizer" by default
  • scriptalizerDirectory: relative path to the desired output location
  • scriptFileList: list of js files in the order you would include them
  • reload (optional) - scriptalizer will inspect each js file for changes made since last access

More about reload: When/if you pass reload=true, <cf_scriptalizer> will inspect each of the source javascript files and if a change is detected, regenerate the combined javascript file.

 

Now that we have reduced the number of connections for external javascript files down to just one for this request, what can we do about reducing the size.

<cf_scriptalizer> takes an additional optional attribute of "minifierObject" as seen in the example below:

<cfset minifier = CreateObject("component","com.cfyuiminifier.cfYUIMinifier").init(path="/com/cfyuiminifier")/>

<cf_scriptalizer 
	filePrefix="myscript"
	scriptalizerDirectory="/js" 
	scriptFileList="
		/js/jquery/jqModal.js,
		/js/jquery/jquery.js,
		/js/jquery/jquery.MultiFile.js,
		/js/jquery/jquery.blockUI.js,
		/js/jquery/jquery.corner.js,
		/js/jquery/jquery.form.js,
		/js/jquery/jquery.history_remote.pack.js,
		/js/jquery/jquery-dom.js
		"
	minifierObject = #minifier#	
	reload="true"
	>

As you can see, I am passing in the object "minifier" that contains the method minify() that accepts a string of all of the comibined javascript and returns a string of the minified javascript.

This additional component was abstracted from the custom tag itself just in case the user has some issue with YUICompressor or wants to implement his/her own solution to compress/clean/minify/etc the source javascript.

In this example, the combined jquery files resulted in a 123.1 KB javascript file (pre-minification). But, once cfyuiminifier.minify() was run on the source, we ended up with a combined javascript file that was only 79.7 KB!

CAVEATS:

I have not yet run this on any live sites.

This is brand new code from my scribble pad, so please be aware you may encounter some bugs!

This was developed on my Linux machine and haven't tested it anywhere outside of this environment.

DOWNLOADS:

 

If anybody has any specific requests for features, or would like to contribute please let me know. I wrote this in an attempt solve a specfic need for some applications I have been working on, and ended up with something I thought might be beneficial to others. Please report back with any successes (or failures) with this tool...I am very interested in hearing about your experience(s).

 

samfarmer said:
 
Very cool. May well be using the tag this summer...
 
posted 50 days ago
Add Comment Reply to: this comment OR this thread
 
Pat said:
 
One nice feature would be if you can 'remove' all JavaScript functions which aren't used or called by other events/functions. This would remove the 'fat' of unused functions.
 
posted 50 days ago
Add Comment Reply to: this comment OR this thread
 
Dan Wilson said:
 
I like this.

I'm going to give it a go this evening. I'll report any issues as they come.
 
posted 50 days ago
Add Comment Reply to: this comment OR this thread
 
 
@Pat - Seems like that could be quite trick to figure out where all the client-side method calls might exist throughout the rest of your code if you don't have them isolated to listener events in your JS files. There are still *many* developers that don't do that!
 
posted 50 days ago
Add Comment Reply to: this comment OR this thread
 
Sami Hoda said:
 
Very nice. Should post on RiaForge. What about something similar for CSS files?
 
posted 50 days ago
View Replies (2) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
Sami, I do plan to add it to RIAForge eventually. I'd like to put it through its paces a few times on a real site before I do though.

A CSS minifier tag should be pretty similar, maybe I'll do that next :)
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
Gary Fenton said:
 
I found a intelligent CSS minifier that analyses the stylesheet markup and makes 'code' changes:
http://iceyboard.no-ip.org/projects/css_compressor...
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
Sami Hoda said:
 
Aaron,
Look forward to it. This is something we can definitely put to use right away. I'm having someone internally evaluate your code. One more thing I'd suggest, besides the CSS, is an option to obfuscate the JS as well. Then you'd have a nice complete system, that passes YSlow's rules for JS.
 
posted 49 days ago
View Replies (1) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
Sami, I made a change to the tag tonight, so if you start using it be sure to grab the current one from the box.
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
Joe Roberts said:
 
I have a similar project for Javascript and CSS files: http://combine.riaforge.org/

It's really good to see a solution to a similar problem, it confirms it's a common problem!
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
jr said:
 
Maybe in writeScriptalizerFile, if the file to include cannot be found it should throw an error or print out a warning to screen since if you have the wrong path to the script file to include it just by passes it without warning so your final script is incomplete.
 
posted 49 days ago
View Replies (1) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
That sounds reasonable, I'll try and get that added in really soon. Thanks for the feedback!
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
Gary Fenton said:
 
I just tried the scriptilizer on your site and it didn't do anything with the js files I selected:

Filesize summary:
Size before: 0.00 KB
Size after: 0.00 KB
0.00KB SAVED!

I tried twice with different files each time. :-(
 
posted 49 days ago
View Replies (6) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
Gary, I have seen a small percentage of files consistently fail for some reason or another. Would you mind emailing me your script so i can run it locally? aaronjlynch AT gmail DOT com
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
 
Ok Gary, it turned out to be a MIME issue with IE...I bet that is the browser you were using right?

Anyways, that doesn't effect the custom tag.

I have fixed the process on www.Scriptalizer.com if you want to try again.

Thanks for checking it out!
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
Gary Fenton said:
 
You were right about me using IE, Aaron. It's only half working now though. It merges the files into a single one, but it appears no minifying is done:

Size before: 367.70 KB
Size after: 367.71 KB
-0.01KB SAVED!

The original js files have not been compressed in any way - lots of white space and a perfect subject for minification.
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
 
@Gary - you have now fallen into the category where we are seeing occasional instances of a file not being minified, as Aaron alluded to above.

I experienced this earlier when grouping about 8 files together. I eliminated them 1 by 1 and got down to one file that appeared to be the offender. Any time that I included that file, minification would not happen. Put the rest back in without it and it would minify fine. We haven't figured out exactly what it is that seems to be causing that yet, but it is a relatively small percentage of submissions overall. I am sure there will be an update about this later, but for now it is a bit of a mystery.
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
 
@Gary... I think I have it fixed now, please try www.Scriptalizer.com again. I have also updated the cfyuminifier.zip to contain the fix, so if you are trying these tools please download the latest.

Thanks to all for testing/reporting!!!
 
posted 49 days ago
Add Comment Reply to: this comment OR this thread
 
 
Update from Gary:

"Bingo!

Size before: 203.88 KB
Size after: 112.32 KB
*91.56KB SAVED!*
Thanks Aaron.

Gary."
 
posted 48 days ago
Add Comment Reply to: this comment OR this thread
 
Josh Nathanson said:
 
Hey Aaron,

Thanks for the great tool.

One thing I noticed is that if you are combining multiple files, each js file must have a semicolon at the end, otherwise, the files run together and everything blows up.

Also, I don't seem to be able to get the minifier to work. I have the component instantiated, but the code that is returned is not minified. Maybe you could clarify the 'path' argument that is passed into the minify object, what is that relative to?

I'm testing this on my local dev box, Windows XP, CF 7.0.2.
 
posted 35 days ago
View Replies (2) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
Josh, one thing that will definitely be an issue is that I used the "sleep" method between iterations of checking the minified temp file. This won't work in CF 7, and will just return the uncompressed js.

 
posted 34 days ago
Add Comment Reply to: this comment OR this thread
 
 
Josh. Dave reminded me, that the necessary line break I added to the assembly process was done in a later version. So be sure to grab the latest zip from box.net. That might fix your ";" thing...
 
posted 34 days ago
Add Comment Reply to: this comment OR this thread
 

Search