Supercharging CSS, Part 1: GZipped and Cached CSS

Firstly, the rewrite rules:

RewriteEngine On
RewriteBase /
RewriteRule ^style/(\w+)\.(\d+)\.css$ /css.php?site=$1&mtime=$2 [L]

Second, the external CSS reference:

<?php
define('SCRIPT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/css/');
define('SCRIPT_PATH', '/style/');

$bundles = array(
  'site' => array(
    'reset.css',
    'superfish.css',
    'site.css',
  ),
);

function link_css($site) {
  global $bundles;
  if (!isset($bundles[$site])) {
    die("css.php: Unknown bundle '$site' requested");
  }
  $mtime = 0;
  foreach ($bundles[$site] as $file) {
    $file_mtime = filemtime(SCRIPT_DIR . $file);
    if ($file_mtime !== false && $file_mtime > $mtime) {
      $mtime = $file_mtime;
    }
  }
  return SCRIPT_PATH . $site . '.' . $mtime . '.css';
}
?>

Third, the reference in the Web page:

<link href="<?php echo link_css('site') ?>" rel="stylesheet" type="text/css">

And lastly, the script the generate the CSS:

<?php
define('SCRIPT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/css/');
define('CACHE_DIR', $_SERVER['DOCUMENT_ROOT'] . '/cache/');

$bundles = array(
  'site' => array(
    'reset.css',
    'superfish.css',
    'site.css',
  ),
);

$site = $_GET['site'];
if (!isset($bundles[$site])) {
  error_log("css.php: Unknown bundle '$site' requested");
  exit;
}

$mtime = $_GET['mtime'];
$cache_file = CACHE_DIR . $site . '.css';
$cache_mtime = @filemtime($cache_file);

// we need to rebuild is the passed in mtime is newer than the cache file mtime
if ($mtime > $cache_mtime) {
  $css = '';
  foreach ($bundles[$site] as $file) {
    $contents = @file_get_contents(SCRIPT_DIR . $file);
    if ($str === false) {
      error_log("css.php: Error reading file '$file'");
    } else {
      $css .= $contents;
    }
  }
  file_put_contents($cache_file, $css);
} else {
  $css= file_get_contents($cache_file);
}

header('Content-Type: text/css');
header('Expires: ' . gmdate('D, d M Y H:i:s', time()+365*24*3600) . ' GMT');
header('ETag: "' . md5($css) . '"');

if (is_buggy_IE()) {
  ob_start();
} else {
  ob_start('ob_gzhandler');
}

echo $css;

function is_buggy_IE() {
  $ret = false;
  $agent = $_SERVER['HTTP_USER_AGENT'];
  if (strpos($agent, 'Mozilla/4.0 (compatible; MSIE ') === 0 && strpos($ua, 'Opera') === false) {
    $version = floatval(substr($agent, 30));
    if ($version < 6) {
      $ret = true;
    } else if ($version == 6 && strpos($agent, 'SV1') === false) {
      $ret = true;
    }
  }
  return $ret;
}
?>

What we have there can already make a substantial difference to site usability and response times.

But why stop there?

Next: Themes

2 comments:

Anonymous said...

This article (WTF?!?!) confirmed my belief that PHP really is just a big pile of poo.

William Shields said...

Um... how so?

Post a Comment