Jump to:

5539 Posts in 1738 Topics by 1224 members

Customising the CMS

SilverStripe Forums » Customising the CMS » Compressing static content

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1344 Views
  • garyw
    Community Member
    1 Post

    Compressing static content Link to this post

    I found a way of speeding up the static publisher a bit by adding a compressed version of each cached file to the cache. The reason why I did this, and didn’t simply use the mod_deflate module or the ob_gzhandler function, was due to the following:

    • mod_deflate and ob_gzhandler dynamically compress data. This is great for dynamic content, but we’re working with static content. It doesn’t make sense to compress a file over and over when we could just compress it once.
    • Some Web hosts may not have the mod_deflate module available.

    Creating compressed versions of static content is a bit tricky, since no function really exists in PHP to generate the exact deflated content that Web browsers expect. Here’s a snippet of the code I used:


    class FilesystemPublisher extends StaticPublisher {
    * Create a second set of cached files that are compressed using the PHP function gzcompress().
    * By default, this is false, but so many browsers support gzip encoding that you should seriously consider setting this to true.
    public static $create_compressed_files = true;
    $files[] = array(
    'Content' => $content,
    'Folder' => dirname($path).'/',
    'Filename' => basename($path),

    // Should we create a compressd version of the file?
    if (self::$create_compressed_files && $this->fileExtension != 'php') {
    $gzsize = strlen($content);
    $gzcrc = crc32($content);
    $gzdata = gzcompress($content);
    $gzdata = substr($gzdata, 0, strlen($gzdata) - 4);

    $files[] = array(
    'Content' => "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $gzdata . pack('V', $gzcrc) . pack('V', $gzsize),
    'Folder' => dirname($path).'/',
    'Filename' => basename($path).'.gz',

    Like I said… a bit tricky. Thankfully this code will only be run when the static cache is generated.

    Here’s the changes made to sapphire/static-main.php:

    // Look for the file in the cachedir
    $file = preg_replace('/[^a-zA-Z0-9]/si', '_', trim($_SERVER['REQUEST_URI'], '/'));
    $file = $file ? $file : 'index';

    $acceptCompressed = (preg_match('/gzip/', $_SERVER["HTTP_ACCEPT_ENCODING"]));
    $fileExtension = '.html';
    $compressedExists = ($acceptCompressed && file_exists('../cache/'.$cacheDir.$file.$fileExtension.'.gz'));

    // If a compressed version of this file exists, output a header that says we're about to send compressed data.
    if ($compressedExists)
    header('Content-Encoding: gzip');
    $fileExtension .= '.gz';

    $gmNow = @gmdate('D, d M Y H:i:s \G\M\T');

    if ($compressedExists || file_exists('../cache/'.$cacheDir.$file.$fileExtension)) {
    $fileToSend = '../cache/'.$cacheDir.$file.$fileExtension;
    header('X-cache: hit at '.$gmNow);
    echo file_get_contents($fileToSend);
    } elseif (file_exists('../cache/'.$cacheDir.$file.'.php')) {
    header('X-cache: hit at '.$gmNow);
    include_once '../cache/'.$cacheDir.$file.'.php';
    if ($cacheDebug) echo "<h1>File was cached</h1>";
    } else {
    header('X-cache: miss at '.$gmNow . ' on ' . $cacheDir . $file);
    // No cache hit... fallback!!!
    include 'main.php';
    if ($cacheDebug) echo "<h1>File was !NOT! cached</h1>";

    It’s somewhat of a cheap hack but it works. On average, it reduces HTML bandwidth by about 80%, and you don’t even need to mess with the Apache or PHP configuration.

  • kaanuni
    Community Member
    22 Posts

    Re: Compressing static content Link to this post

    Is there an updated way to do this in ss3?

Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.