Optimizing Google Analytics Performance

[ Image: Global Map Icon ] It has occurred to me lately that I no longer use Google Analytics for Perishable Press. Instead, I find myself keeping an eye on things using Mint almost exclusively. So, the question now is: do I continue serving the GA JavaScript to keep the profile active just in case I ever need the additional stats? I mean, Mint already does a great job at recording all of information I could ever need, so I no longer see the use for Google Analytics. I do wonder, however, if Google ranks GA-enabled sites a bit higher than non-GA sites. Hmmm.. it seems to me that there are several options going forward..

Option 1: Continue with Google Analytics

The easiest thing for me to do at this point would be to just leave it alone: continue serving the extra 6.3K/21.4K GA JavaScript (i.e., urchin.js) to site visitors. Sure, I may never actually use the volumes of data I am collecting via Analytics, but hey, who cares, right? Of course, delivering the urchin.js file requires bandwidth and other server resources, and also tends to slow things down a bit, especially on those rare occasions when the Google server bogs down.

Option 2: Stop using Google Analytics

If I decide to discontinue Google Analytics altogether, I would need simply to edit my footer.php file to remove the GA code. If I do this, my site will require fewer resources, consume less bandwidth, and enjoy faster loading times. Increased site performance is a huge factor for me. Anything I can do in order to optimize performance and enhance the user experience is at the top of my list. Plus, not everyone enjoys being tracked statistically, nor does everyone surf the Web with JavaScript enabled/available. At this point, dropping GA entirely is looking better and better..

Option 3: Serve the urchin.js file locally

One of the main reasons why killing Analytics seems so attractive is the (slightly) faster page-loading times that would be enjoyed without it. Thus, a third option for dealing with my currently unused GA setup involves optimizing performance by serving the requisite urchin.js file locally. The simplest way to do this is to download a copy of the file to your server and call it directly by changing the standard code generally located in your footer:

<!-- notice the address change in the next line to serve urchin.php locally -->
<script src="http://perishablepress.com/stats/urchin.js" type="text/javascript"></script>
<script type="text/javascript">
	_uacct = "UA-332938-1";
	urchinTracker();
</script>

This would be ideal, if it weren’t for the fact that Google periodically changes the urchin.js file. They do this infrequently enough (approximately once per year) that manually updating a couple of times a year would be less work than actually remembering to do it.

Option 4: Run a script to cache urchin.js locally

To host the file locally without relying on my frail human memory to update it, I could implement a PHP script to cache a local copy and periodically check for updates. Seriously considering this option, I began researching for code snippets that would help me fashion such a script. As it turns out, however, an engineering student from India named Joyce Babu wrote a script for this exact same thing several months ago:

<?php // source: http://www.joycebabu.com/blog/speed-up-google-analytics-using-simple-php-script.html

// Remote file to download
$remoteFile = 'http://www.google-analytics.com/urchin.js';
// Local File name. Must be made writable
$localFile = "local-urchin.js";
// Time to cache in hours
$cacheTime = 24;
// Connection time out
$connTimeout = 10;
// Use Gzip compression
$useGzip = true;
 
if($useGzip){
     ob_start('ob_gzhandler');
}
 
if(file_exists($localFile) && (time() - ($cacheTime * 3600) < filemtime($localFile))){
     readfile($localFile);
}else{
     $url = parse_url($remoteFile);
     $host = $url['host'];
     $path = isset($url['path']) ? $url['path'] : '/';
 
     if (isset($url['query'])) {
          $path .= '?' . $url['query'];
     } 
 
     $port = isset($url['port']) ? $url['port'] : '80';
 
     $fp = @fsockopen($host, '80', $errno, $errstr, $connTimeout ); 
 
     if(!$fp){
          // On connection failure return the cached file (if it exist)
          if(file_exists($localFile)){
               readfile($localFile);
          }
     }else{
          // Send the header information
          $header = "GET $path HTTP/1.0\r\n";
          $header .= "Host: $host\r\n";
          $header .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6\r\n";
          $header .= "Accept: */*\r\n";
          $header .= "Accept-Language: en-us,en;q=0.5\r\n";
          $header .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
          $header .= "Keep-Alive: 300\r\n";
          $header .= "Connection: keep-alive\r\n";
          $header .= "Referer: http://$host\r\n\r\n";
 
          fputs($fp, $header);
 
          $response = '';
          // Get the response from the remote server
          while($line = fread($fp, 4096)){
               $response .= $line;
          } 
 
          // Close the connection
          fclose( $fp );
 
          // Remove the headers
          $pos = strpos($response, "\r\n\r\n");
          $response = substr($response, $pos + 4);
 
          // Return the processed response
          echo $response;
 
          // Save the response to the local file
          if(!file_exists($localFile)){
               // Try to create the file, if doesn't exist
               fopen($localFile, 'w');
          }
          if(is_writable($localFile)) {
               if($fp = fopen($localFile, 'w')){
                    fwrite($fp, $response);
                    fclose($fp);
               }
          }
     }
}
?>

Simply upload his script and edit your analytics code to call for it instead of calling for the urchin.php file itself. The script then downloads a fresh copy of urchin.php at the specified time interval. The upside is that the script eliminates the need to manually remember and replace the file, however the downside is that the script runs for every page load. If it weren’t for that, this would be the ideal solution. Joyce even created an enhanced WordPress plugin to simplify the entire process.

Option 5: Invoke the powers of cron

As mentioned, the only downside to running a caching script to keep a locally served urchin.php file fresh and delicious is the perpetual processing of the script itself. Fortunately, we may call upon the mighty powers of cron to schedule automatic script execution at specified intervals. Using a cron job to execute the urchin.php-update script ensures file freshness without having to constantly run the script — once a week (or however often you choose) does the job. In measured-memory environments or on setups with other resource restrictions, conserving processing power via cron is ideal. Simply upload the script and create a cron job as follows:

/usr/local/bin/php /home/username/path/to/script.php >/dev/null

..or, alternately (in cPanel):

/usr/local/bin/php -q /home/username/path/to/script.php

After setting up this command with the desired processing interval, the update script will quietly keep your copy of urchin.php updated with the current version. Finally, if using this method, remember to call your local copy of urchin.php (instead of the update script itself) as per the code presented in “Option #3”, above.

Option 6: Upgrade to the new Google Analytics

I can’t believe I missed this during my initial write-up. As astute reader Louis points out, Google has completely upgraded its Analytics program, including a complete rewrite of the original JavaScript used in the omnipresent urchin.js script. According to reports, the new code — ga.js — is leaner, faster and smarter, capable of event tracking, cross-browser caching, and object-oriented functionality. In short, it rocks. Although I have not yet had the opportunity to fully investigate this new scriptness, it may very well be the solution for which I am looking — locally hosting and automatically upgrading the new ga.js file may not even be necessary given the optimized nature of the script. Enough for now, here is the complete code required to start using the new Google Analytics this very moment:

<script type="text/javascript">
     var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
     document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
     var pageTracker = _gat._getTracker("UA-XXXXXXX-X");
     pageTracker._initData();
     pageTracker._trackPageview();
</script>

A little messy, but hey, who cares, right? Note that it is critical to use either the old GA code or the new GA code, but not both. Simply replace your previous Google Analytics code with this new version and you are good to go! Don’t forget to edit the “UA-XXXXXXX-X” to reflect your actual GA account number.

Da wrapz..

As far as I am able to tell, these are the most reasonable solutions for optimizing and/or dealing with your (possibly unused) Google Analytics configuration. The important thing here is to be mindful of your involvement with GA — are you actually benefiting from Analytics, or has it fallen into disuse, like that old exercise bike gathering dust in the basement? If you use it, optimize it. If not, why waste resources at all? Although I remain undecided at this point, chances are high that Google Analytics will disappear completely during the next site redesign.

What about you? Are you using Google Analytics, and if so, how often do you examine the results? Do you use other statistical applications as well? What is your strategy for statistics?