Forum Moderators: DixonJones
A lot of people seem to be interested in measuring the total download speed of their site. Some wise among them look to find out how fast the site will load before they make it a production web site. Other, like me, are stuck trying to figure it out afterwards.
So below is a little howto on tracking download speed of users who have JavaScript enabled. This approach also allows you to track the users' screen resolution, browser window dimensions, color depth, pixel depth, etc. (These additional tracking is only useful for educations purposes: i.e. to see for yourself that from 40% to 50% of users still use 800x600 or less monitor screen resolution).
This is not the most precise approach (only users with JavaScript, an added request for a 1x1 pixel image), but for most sites like mine it will do fine. Can't beat real-life data.
What you will need:
1. A table in your backend database that will be only used to store the information tracked in this way, and not for your general session tracking. I'll explain why later. (I use MySQL, most people do).
2. An small 1x1 pixel transparent GIF image that is not crucial to your web page's look. Users without JavaScript will never see it. This image will be requested by the browser on page load, and will be generated by a server-side script (I use PHP on Linux) that will first log the collected information.
3. A javascript function, that will change the SRC attribute of the tracker image.
4. An onLoad event handler for the BODY html element.
5. A script on your server that will do the logging and output a raw image and which the tracker image uses as its SRC. It can be part of your session tracking code, or a stand-alone script. I'll call it gen_image.php
1. Here's the structure of your backend table:
DROP TABLE IF EXISTS `js_tracking`;
CREATE TABLE `js_tracking` (
`session` CHAR(32) NOT NULL,
`screen_width` SMALLINT NULL,
`screen_height` SMALLINT NULL,
`inner_width` SMALLINT NULL,
`inner_height` SMALLINT NULL,
`color_depth` TINYINT NULL,
`pixel_depth` TINYINT NULL,
`request_complete` INT NULL
);
request_complete will be used to track the Unix timestamp of the second request to the gen_image.php script. The first one will be stored in your main session-tracking table.
2. In our example it's location of the image will be /home/ctpat3r/www/images/clear_dot.gif.
The tracker IMG tag, pointing to the tracker PHP script should appear relatively soon in your html, since we'll use it to track the speed of download for the user. The image will be rendered by JavaScript, but it also needs to contain the session id you generate in your PHP code, so that we can correlate the data to the main session-tracking data (user-agent, remote address, referer, query string, etc.)
Here's sample code:
<?php
print "
<script language=\"javascript\">
document.writeln(\"<img name='tracker'
src='/gen_image.php?s=".session_id()."'
border='0'
alt='tracker'>\");
</script>";
?>
Note that I'm using the PHP function session_id() to generate the session id string, for illustration purposes. We also need a name for the image, to be used in the javascript function. You also should put in some php code that will make sure this JavaScript code snippet, the BODY tag's onLoad event specification and the JavaScript function below is printed to the browser only on the first visit for each session. No point in tracking speed of download of subsequent pages, because it will most likely be faster than the first page, due to image caching by the browser.
3. Here's the javascript function, that you will either link to from you page or print it as part of the web page:
function set_tracker_source() {
var imgSrc = "";
if(window.screen) {
imgSrc =
"&w=" + window.screen.width +
"&h=" + window.screen.height +
"&cd=" + window.screen.colorDepth +
"&pd=" + window.screen.pixelDepth;
}
imgSrc +=
"&iw=" + window.innerWidth +
"&ih=" + window.innerHeight;
document.images["tracker"].src = imgSrc;
}
4. Add this to your BODY html tag:
... onLoad="javascript: set_tracker_src();">
This will cause the visitor's browser to make a request to get_image.php in order to change the source for the tracker image tag. gen_image.php below will do that, but first it will log javascript information provided by the set_tracker_src() function.
5.
And finally the source for the gen_image.php script. Check whether this is the first time it's called for the given session and, if so, log all the information provided in the GET header. Then output the image. As of this writing (2003), you will discover that almost 50% of your visitors have screen resolution of 800x600 and about 15% use 16 bit color depth (256 colors).
<?php
function process_js ($session = null) {
if(!$session) {
return;
}
// login to the database here
// import your own function for logging errors here
$sql = "SELECT * FROM `js_tracking`
WHERE `session` = '$session'";
if($r = mysql_query($sql)) {
$row = mysql_fetch_assoc($r);
mysql_free_result($r);
} else {
log_mysql_error($sql, 'gen_image', 0);
return;
}
if(!$row) {
$sql = "
INSERT INTO `js_tracking`
(`session`)
VALUES
('$session')
";
if(!$r = mysql_query($sql)) {
log_mysql_error($sql, 'gen_image', 0);
return;
}
} elseif ($row['request_complete']) {
return;
} else {
$sql = "
UPDATE `js_tracking`
SET
`screen_width` = '".$_GET['w']."',
`screen_height` = '".$_GET['h']."',
`request_complete` = ".time().",
`inner_height` = '".$_GET['ih']."',
`inner_width` = '".$_GET['iw']."',
`color_depth` = '".$_GET['cd']."',
`pixel_depth` = '".$_GET['pd']."'
WHERE `session` = '$session'
";
if(!$r = mysql_query($sql)) {
log_mysql_error($sql, 'gen_image', 0);
return;
}
}
}
process_js($_GET['s']);
header("Content-Type: image/gif");
passthru("cat ./images/clear_dot.gif");
?>
I use a rough estimate to determine if a user is on dial-up or not. My site is poorly optimized and heavy on graphics so I assume that if it takes a user more than 5 or 6 seconds to download the site, they must be on dial-up or coming from a poorly connected region of the world.
I wasn't responsible for the design, just for the backend code. I came up with the technique to collect some hard data to show the designer that he better get up to speed on usability and not just concentrate on eye-candy.