interceptor to defer JavaScript

This is the interceptor I was just telling Jeremy about that uses the preRender interception point to defer all the JavaScript includes in my app to the bottom of the page on the recommendation of the Yahoo! developer guidelines that points out browsers wait to render any part of your page after a script block until all JavaScript in that tag been downloaded and processed.
http://developer.yahoo.com/performance/rules.html#js_bottom
The only catches I’ve found is usage of document.write() and events declared in your tags like

will throw an error until your JS has finished loading. The easy solution would be to bind those events with jQuery on document ready.

I’m posting it here for two reasons:

  1. So Jeremy has an example to use
  2. I’ve been meaning to throw it out there for a while to see what people think.

Luis, I just saw your reply. Yes, I will submit it, but I think last time I checked you had to sign up for a ForgeBox account to post. Is that still correct?

Thanks!

~Brad

// Note, this interceptor will not affect JavaScript placed on the page via cfhtmlhead or cfajaxproxy tags. // Those are appended to the output buffer after ColdBox is finished. It is possible to snag those too, but you // will have to dig into undocumented portions the Java HTTPRequest object. // // Also note, if you have any JavaScript doing something like document.write() you probably DON'T want it moved. // In that instance, a way needs to be established to "exempt" a script tag from this regex.

var local = {};
// Regex to match script tags.
local.regex = “<[\s/]script\b[^>]>[^>]*</script>”;
// String buffer to avoid exessive string memory usage.
local.javaScriptToDefer = createObject(“java”,“java.lang.StringBuffer”).init(javaCast(“int”, 4000));
// carriage return, line feed
local.crlf = chr(13) & chr(10);

local.result = reFindNoCase(local.regex,interceptData.renderedContent,1,true);
// Loop as long as their are more tags in the document.
while(local.result.len[1])
{
// Add this script tag into the buffer…
local.javaScriptToDefer.append(javaCast(“string”, local.crlf));
local.javaScriptToDefer.append(javaCast(“string”, mid(interceptData.renderedContent,local.result.pos[1],local.result.len[1])));
// …and keep searching
local.result = reFindNoCase(local.regex,interceptData.renderedContent,local.result.pos[1]+local.result.len[1],true);
}
// Strip out all script tags and append them to the end. interceptData is a struct so it is passed by reference. No need to return any data.
interceptData.renderedContent = reReplaceNoCase(interceptData.renderedContent,local.regex,"",“all”) & local.javaScriptToDefer.toString();