Check request compression savings

Gzip compression is almost universally recommended as a basic step to improving site performance. It basically uses a little bit of extra processing on the server and client to significantly reduce the transfer size of most text responses. In Apache, this is done with mod_deflate (see the H5BP config for an example of how to set this up).

A while back, I was setting gzip up on my server, and wanted a simple way to verify that it was working and check how much transfer was saved. One simple way to verify it is working is with curl on the command line. If you run curl -I -H 'Accept-Encoding: gzip,deflate' example.com and see the header Content-Encoding: gzip, compression is working. To test the transfer savings, I wrote a simple script using PHP’s curl library. It makes a request with and without the Accept-Encoding: gzip,deflate header, and compares the transfer data info provided by curl_getinfo().

The script is run from the command-line like checkGzipCompression http://example.com. It looks like:

#!/usr/bin/env php
<?php
$url = $argv[1];

function runRequest($url, $opts = Array()){
    $opts = array_replace(Array(
        CURLOPT_HEADER=> true
        ,CURLOPT_RETURNTRANSFER=> true
    ), $opts);
    $ch = curl_init($url);
    curl_setopt_array($ch, $opts);
    $result = curl_exec($ch);
    $chInfo = curl_getinfo($ch);
    curl_close($ch);
    return $chInfo;
};

$uncompressedRequestData = runRequest($url);
$compressedRequestData = runRequest($url, Array(
    CURLOPT_HTTPHEADER=> Array(
        'Accept-Encoding: gzip,deflate'
    )
));
$data = Array(
    'uncompressed'=> Array(
        'label'=> 'Without Gzip'
        ,'headerSize'=> $uncompressedRequestData['header_size']
        ,'contentSize'=> $uncompressedRequestData['size_download']
    )
    ,'compressed'=> Array(
        'label'=> 'With Gzip'
        ,'headerSize'=> $compressedRequestData['header_size']
        ,'contentSize'=> $compressedRequestData['size_download']
    )
);
foreach($data as $key=> $item){
    $data[$key]['total'] = $item['headerSize'] + $item['contentSize'];
}
$data['savings'] = Array(
    'label'=> 'Savings'
    ,'headerSize'=> $data['uncompressed']['headerSize'] - $data['compressed']['headerSize']
    ,'contentSize'=> $data['uncompressed']['contentSize'] - $data['compressed']['contentSize']
    ,'total'=> $data['uncompressed']['total'] - $data['compressed']['total']
);
foreach(Array('headerSize', 'contentSize', 'total') as $field){
    $data['savings'][$field . 'Percentage'] = $data['savings'][$field] / $data['uncompressed'][$field] * 100;
}
$fields = Array(
    'Header Size'=> 'headerSize'
    ,'Content Size'=> 'contentSize'
    ,'Total Size'=> 'total'
);
foreach($data as $item){
    echo $item['label'] . ":\n";
    foreach($fields as $label=> $key){
        echo "\t{$label}: {$item[$key]} bytes";
        if(isset($item[$key . 'Percentage'])){
            echo " (" . number_format($item[$key . 'Percentage'], 3) . "%)\n";
        }else{
            echo "\n";
        }
    }
}

and produces output like:

Without Gzip:
    Header Size: 559 bytes
    Content Size: 8885 bytes
    Total Size: 9444 bytes
With Gzip:
    Header Size: 583 bytes
    Content Size: 3337 bytes
    Total Size: 3920 bytes
Savings:
    Header Size: -24 bytes (-4.293%)
    Content Size: 5548 bytes (62.442%)
    Total Size: 5524 bytes (58.492%)

Published by

Toby

I am a quiet person from Northeast Ohio. I work as a web developer. I like computers, music, and many other things.

Leave a Reply

Your email address will not be published. Required fields are marked *