One of my favorite things about ColdFusion is the level of detail you can get from the debugging information. The ColdFusion server will provide upon request and the right permissions: variable scopes, sql query information, server information, and execution / load times. This is very useful information to have while coding and is invaluable when you are trying to optimize the speed and performance of the site. However, is it hard to get good benchmark for this data over time from the perspective of your end users.
Earlier this week, I set out to see if there was a way I could get access to the page load data and send it along to Omniture so that I could first get a benchmark of what the performance of the web site was over time, and second be able to tell if changes we made to the site had any impact on performance.
My first attempt in accomplishing my goal was to try and access the same Java object that the debugging code used to get the execution times. I thought, well I see it in the output on the screen, it should be easy enough to grab that data element and pass it along.
<cfset codeFactory = CreateObject("java","coldfusion.server.ServiceFactory") /> <cfset getDebugDataSet = codeFactory.getDebuggingService()> <cfset getDebugData = getDebugDataSet.getDebugger().getData()>
This call returned an object that I was able to parse using the same methods you would use to parse a query object. It ran great on my development box, but when I moved it to production: Fail. ColdFusion provided this lovely error message:
Detail Its possible that a method called on a Java object created by CreateObject returned null.
I tried adjusting a few settings and was not able to resolve the issues. I reached out to the Atlanta ColdFusion community, and received some very good guidance on the matter. The reason for the error was I had debugging enabled on my development box, but did not on my production server. And no matter what creative method I could come up with, would not justify enabling debugging on a production ColdFusion server. The performance loss by doing this would outweigh the data gained.
The method that turned out to be the best, was also the easiest. ColdFusion applications can take advantage of a global application file and two great methods within it: onRequestStart() and onRequestEnd(). The functions do exactly as their names would suggest, they will execute the code within each of them at the start and end of every request for every page in the application.
So inside the onRequestStart() function, you get a start time. And within the onRequestEnd() you get the end time and take the difference to get the page load time in milliseconds. Pseudo code below:
<cfset startTime = getTickCount() /> <!--- something that you want to measure ---> <cfoutput>That took #(getTickCount()-startTime)#ms!</cfoutput>
Now I have the the page load times and I began to pass the data into Omniture. Soon I had results like this.
It did not take long to determine that data in this format would not be very useful as I could have values from 0 to in excess of 10,000 milliseconds. So I created a quick SAINT classification and was able to group the data together into more logical sections.
Now, this was better, but not perfect and I did not like the data groupings and the time being reported into milliseconds. After thinking a bit on this, I decided to convert the time to seconds on the ColdFusion side and do the grouping on the web side as well. I grouped the data into the following sections and passed the data into an sProp:
- < 1 Second
- 1-2 Seconds
- 2-3 Seconds
- 3-5 Seconds
- > 5 Seconds
I then took this data and concatenated it with the page name to send in a second sProp: < 1s | Home Page. Doing this gave me these sets of data.
Note: These may not be the absolute accurate page load times, but they will be close enough to get a good idea of overall site performance.
Success! Now, before and after major code changes to the site we will be able to go and see if the changes we made had an impact on the performance of the site. So why go through all the effort to put this into Omniture, when there are other methods to get this type of performance data? Now that you are able to send this data to Omniture, what else could you do with it?
- Send it in an eVar to see how performance impacts conversions.
- Apply a bounce rate metric to see how performance impacts bounce rates.
- Justify the modification or removal of slow pages/functionality.
- Add pathing to the second concatenated sProp to see how users move through the site with performance
These are just a few ideas I had. What would you do with this data inside of your Analytics tool if you could?