Proof of Concept
Tags: Coldfusion
After having be given a task, and one of the requirements was to produce a prototype of a new intranet application for a version 2 of an existing application. Now as this prototype was to pave the way for the reason to move forward, I had a challenge that some extranet users would be in remote locations and that provided a problem. So what was my solution, well my first thought was to look into compressing the data before sending it to the browser, now I had another problem, there was no guarantee that any 3rd party software would be usefull for a platform independant solution.
So investigating something that I had toyed with a few years ago I began looking into Application.cfc and using that to see if I could make the page compressed before sending it the browser.
So as a delved into this I found a php solution that seemed to do what it was I wanted, but I looked at a java solution that would integrate in CFMX6.1+ and after a few helpful people on CF Aussie, Mark Mandel for getting me to the final stages and Rod Higgins for getting me in the right direction.
So what is the solution, well this solution zips up the current request content and serves it back to the browser, now as our application is a heavy ajax solution this became ideal for a platform independant solution that reduces the time for data to reach our remote dial up users as there is a lot of data being bounced around via ajax calls.
Anyway here is the solution.
<cffunction name="onRequestEnd" returntype="boolean" output="true">
<cfargument name="thePage" type="string" required="true">
<cfset var fileOut = '' />
<cfset var out = '' />
<cfscript>
pageOut = getPageContext().getCFOutput().getString();
fileOut = createobject("java", "java.io.ByteArrayOutputStream").init();
out = createobject("java","java.util.zip.GZIPOutputStream").init(fileOut);
out.write(variables.pageOut.getBytes(), 0, len(variables.pageOut.getBytes()));
out.finish();
out.close();
</cfscript>
<cfheader name="Content-Encoding" value="gzip">
<cfcontent type="text/html" reset="true" variable="#fileOut.toByteArray()#">
<cfreturn true />
</cffunction>
-
I should also point out that this is a concept, and that one really should decide first if the browser can infact support the compression before doing so.
# Posted By Andrew Scott | 9/12/06 6:07 AM -
Interesting stuff. As an addition, note that you can determine if the browser would support it by first testing if cgi.http_accept_encoding contains "gzip".
# Posted By Charlie Arehart | 9/12/06 1:49 PM -
one other thought, Andrew: I had a heck of a time entering my last comment (and even this one) because the captcha that you have was tough for me to get right. I've written a blog entry on how you can very easily fix that:
Simplifying the captcha graphic in Lyla Captcha (and BlogCFC)
http://carehart.org/blog/client/index.cfm/2006/8/1...
It's been great for both my commenters and for me so far (no spam for me, no hassles for users). I hope you'll consider it.# Posted By Charlie Arehart | 9/12/06 1:53 PM -
Charlie,
Thanks for your feedback, I woulod be interested to hear more on the captcha. I was really under the impression that this is what was being used here:-)# Posted By Andrew Scott | 9/12/06 6:53 PM -
Thanks charlie I didn't know about the xml file to make changes to the Lyla Captcha.
Many thanks# Posted By Andrew Scott | 9/12/06 7:07 PM -
Have you checked into compression on the web server portion? It seems like that would be a faster solution.
# Posted By Marlon Moyer | 9/14/06 10:12 AM -
Interesting solution. However, the one question I have is what happens when you want the response to be something other than text/html? Say I have a bunch of PDFs that can't be in the web root for security reasons, so I want to serve them using the cfcontent tag? Doesn't the text/html in your code snippet break that? Same thing with wanting to return XML (i.e., returning an XML packet from an xmlHTTP request)? Just curious.
# Posted By Dave Carabetta | 9/14/06 10:16 AM -
Hi Andrew, I'm impressed with this tech!
I've tried it (using OnRequestEnd.cfm) and it works great, from 31KB to 6 KB is quite the bandwith saver.
One thing I encountered though, and I'm not sure this same thing hapens if you use the App.cfc way, is that <cfhtmlhead> doesn't work anymore.# Posted By Mingo Hagen | 9/14/06 10:16 AM -
@Dave Carabetta
I tried it with an image served up through a <cfcontent> / <cfheader> and it works as well, however the image did not get compressed more, but that usualy is the case with already compressed files (it was a jpg).# Posted By Mingo Hagen | 9/14/06 10:21 AM -
Very interesting, however I would have to agree with Marlon about using the web server. I can't foresee what problem this solves that the web server level can't already do better since that implementation has been around for a longer time. Also, as Dave points out - there could be unforeseen problems when serving content that is not text/html. Andrew, I'm just curious what problem you are trying to solve with your proof of concept or is just something fun to investigate? If it's just plain old programming fun, that this is very cool. If it's a problem, I think that you're maybe using CF to do something that the web server tier of your platform will handle in a more robust (and proven) manner. My $.02...
# Posted By Peter J. Farrell | 9/14/06 12:56 PM -
I was a little surprised to hear that it does do images as well.
On the note of setting the server to do the compression, why do we all make the assumption that we can get to the server to make the change in question. Not all developers have the oppurtunity to get away from shared hosting.# Posted By Andrew Scott | 9/14/06 5:59 PM -
another fun, but useless, feature of postprocessing your page is that you can run some sort of htmlTidy over your html, and use that to brag to the girls about how extremely neat your code looks...
# Posted By Mingo Hagen | 9/15/06 10:43 AM -
An interesting approach to compression. Although I suspect that an Apache mod may be faster.
An alternative approach to using Java, or for those situation where you cannot use createObject, woudl be to use the HtmlCompressFormat udf from CFLib (http://www.cflib.org/udf.cfm?ID=812). It uses a regex to remove whitespace etc that increases the file size.
regards,
larry# Posted By Larry C. Lyons | 9/15/06 1:36 PM -
this is awesome. unfortunately, from my tests, it seem like it will screw the output of the scripts using cfform. it will just not show up the JS generated by coldfusion.
# Posted By Ed | 10/1/06 11:50 AM -
Ed,
Not sure how or what your doing, but I use this in a development environment with no problems running JS in a page or even loading JS either.# Posted By Andrew Scott | 10/3/06 2:47 AM



TweetBacks