Tip to Speed Up Your Website - Compress CSS

There are a number of ways to speed up a website. An easy one would be to compress asset files and compact the files. This has been widely done for Javascript files with popular tools such as JSMIN and Packer.

The general idea behind compression/combination is to reduce the number of characters that must be sent over the wire as well as reduce the number of HTTP calls that must be made. Each time a browser gets a request to download a JS file, there is a certain amount of overhead incurred in negotiating and completing the HTTP request. Combining all JS files into one file is a great way to speed up a web application.

Everyone Already Knows This, Right?

Probably. However, CSS files can often be as numerous and verbose as Javascript files. How come there no public outcry for CSS compression/combination?

There happens to be a compressor/combinator that handles CSS files, the YUI Compressor. For most web application developers, YUI Compressor is an annoying tool to use because, as a java application, it must be installed and run from the command line. Yuck!, right?

Scriptalizer, developed by ColdFusion luminary Aaron Lynch, is a web front end for the YUI compressor. Scriptalizer has handled Javascript compression/combination for a while now and is a nicely designed, easy to use tool. Aaron recently added support for CSS compression/combination. Now, dealing with CSS files is as simple as dealing with JS files.

How well does it work?

I added all 14 CSS files from The Health Challenge and compressed/combined them with Scriptalizer. Here are the results:

  • Number of Files Before: 14
  • File Size of All Files: 35.42 KB
  • Number of Files After: 1
  • File Size of All Files: 19.96 KB

As you can see, the reduction was significant. Not only have I cut the size of my CSS assets by ~50%, I have also removed 13 HTTP connections.

OO Code Camp Starts This Week

In 2009, TACFUG will put on a free series of courses on Object Oriented programming in ColdFusion. We originally had slots for 20, constrained by the size of our location, and we are pretty much at capacity.

We realized this topic would have broad appeal and tried to creatively think of a way to record these sessions. Frankly, the material and the characteristics of our location does not lend itself to recording this meeting.

As a consolation prize, we will make the material used in OO Code Camp available to any other User Group that wants to use it. Just drop us a line at the TACFUG site, we'll get it over to you.

Thanks go to Alagad for sponsoring the series with Pizza. Thanks also to Doug Hughes and to Phill Nacelli for letting us use their previous OO presentations for ideas/content.

Fix for: 500 Null Corrupt form data: no leading boundary

Another 500 Null Error / Solution

I ran into a strange error in the registration section of TheHealthChallenge.com where Internet Explorer users (Editors Note: Remove defamatory comments re: Internet Explorer Development Team and gratuitious comparisons about the size of their brains vs. size of their egos ) clicking a button would cause a 500 Null.

Here are the error details:

view plain print about
1500
2Corrupt form data: no leading boundary: != -----------------------------7d93d92a60680
3
4
5java.io.IOException: Corrupt form data: no leading boundary: != -----------------------------7d93d92a60680
6    at com.oreilly.servlet.multipart.MultipartParser.<init>(MultipartParser.java:174)
7    at com.oreilly.servlet.multipart.MultipartParser.<init>(MultipartParser.java:93)

Can anyone venture a guess as to what the problem was? You want more information? Take a look at the form code as well:

Here is the HTML for the Form:

view plain print about
1<form action="index.cfm?x=register" method="post" enctype="multipart/form-data" id="registerForm" class="uniForm">
2    <fieldset class="inlineLabels">
3        <div class="ctrlHolder">
4            <label for="register"> Need an Account?</label>
5            <p class="formHint">registration takes only 53 seconds</p>
6        </div>
7    </fieldset>
8        <div class="buttonHolder">
9            <button type="submit" class="submitButton">Start Registration</button>
10        </div>
11</form>

By the looks of the HTML code above, a single button will be drawn on the screen along with some friendly text. So why the error?

Solution

Apparently Internet Explorer does not handle serializing the form post if there is no content and what it sends to the server is not what the server expects. Possible resolutions for this are to remove the [enctype="multipart/form-data"] attribute or change the [method="post"] to [method="get"]. Either one will work as intended.

I happened to create this set of circumstances by using the CFUniform library in a way it was not designed for. I mentioned this to Matt Quackenbush who reworked the inner workings of the CFUniform Library to intelligently figure out if a file upload control is in the form or not. If one exists, the [enctype="multipart/form-data"] attribute will be included automatically. If you experience the 500 Null problem listed in this post, and you are using the CFUniform Library, simply update your version from http://cfuniform.riaforge.org/ and you'll be all set.

CFQueryparam and Lists

A word on SQL Injection

SQL Injection is a pervasive problem in the Web Application World. A quick search for URLS that use raw SQL brings up hundreds of thousands of dangerously formed URLS. Any developer worth his salt knows to clean user input before using it.

Defend Against SQL Injection in ColdFusion

CFQueryparam is a recommended tag that helps to keep your queries safe from SQL Injection. Any ColdFusion worth his salt uses CFQueryparam to help keep malicious parameters from being executed by the database engine. I ran across some code today that used CFQueryparam in most cases, but there was a particular, recurring use case that used raw parameters.

Example 1

view plain print about
1<cfquery name="getProductsByList" datasource="ILikeTwinkies">
2SELECT productName,
3FROM product
4WHERE productID IN ( #productIDList# )
5</cfquery>

Note the use of the list. It is a common paradigm to pass a delimited list of data to an SQL statement. In this case, the developer chose not to use CFQueryparam because he/she was under the impression that the result would be a single parameter, not a chain of parameters.

However, CFQueryparam can be used successfully in this case by setting the optional attribute 'list' to true. This is a supported attribute on all database engines.

Example 2

view plain print about
1<cfquery name="getProductsByList" datasource="ILikeTwinkies">
2SELECT productName,
3FROM product
4WHERE productID IN (<cfqueryparam value="#productIDList#" list="true" cfsqltype="cf_sql_numeric">" )
5</cfquery>

The resulting query will be parametrized in such a way as to render the list as a list and the results of the second query are equal to the first. Except for the case of an SQL Injection attack.

In the case of an SQL Injection attack, the developer of the first code sample would have a lot of explaining to do...

Must Have Tool For Ajax/Remoting Work!

Nathan Mische, one of the best JavaScript programmers I know, works on the ColdFire project. ColdFire is sort of like Firebug for Firefox, only geared towards ColdFusion.

If you've developed any sort of Ajax functionality, you know testing remote services can often be frustrating. Trying to get a handle on what parameters are being passed, how to send test parameters, knowing what the results of the request were, often mean dealing with a number of problem layers and a lot of confusing Red Herrings.

If you do any Ajax work, take 72 seconds out of your life to watch this quick screencast on the Request Queue in ColdFire.

See how efficient the workflow is? See how quick one can test remote services? How much time would this save you, what with all the cfdumping, the alerts, the aggravation?

What are you waiting for? Download ColdFire Now!

What Is ColdFire?

ColdFire is an extension to Firebug. It provides debug information in a Firebug tab as opposed to the bottom of the page. This lets you debug and keep your site layout intact, since ColdFusion's built-in debug information can sometimes mess with your site layout. ColdFire currently shows debugging information in the following tabs:

  • General
  • Execution Times
  • DB Queries
  • Traces
  • Timer
  • Variables
  • Request Queue