Categories

HTTP Compression

Posted on: September 16, 2019 by Dimitar Ivanov

Speed is everything. There is no doubt that the faster websites gets higher rank in SERP and provides better user experience.

What is compression

HTTP compression is a built-in mechanism into web servers and browsers for reducing the size of transferred data between them.

Compression scheme negotiation

  • The browser appends the Accept-Encoding header to the request. This header defines the acceptable content-encoding, mainly supported encryption.
    GET /index.html HTTP/1.1
    Host: zinoui.com
    Accept-Encoding: gzip, deflate, br
    
  • Then the server includes the Vary and Content-Encoding headers to the response.
    HTTP/1.1 200 OK
    Server: Apache
    Vary: Accept-Encoding
    Content-Encoding: gzip
    Content-Type: text/html; charset=utf-8
    Content-Length: 4079
    Accept-Ranges: bytes
    Date: Sat, 06 Feb 2016 11:53:16 GMT
    

How to enable HTTP compression on Apache

To append the Vary header use Header directive:

<IfModule mod_headers.c>
  <FilesMatch "\.(html|css|js)$">
    Header append Vary: Accept-Encoding
  </FilesMatch>
</IfModule>

The mod_deflate and mod_brotli modules provide respectively the DEFLATE and BROTLI_COMPRESS output filters that allow output from your server to be compressed before being sent to the client over the network.

There are two ways to use filtering: Simple (traditional) and Dynamic (smart filtering).

  • Simple way - using this way you can not add conditions. Simple way is already deprecated. Use dynamic configuration instead.

    To compress by filename extension use AddOutputFilter directive:

    <IfModule mod_deflate.c>
      AddOutputFilter DEFLATE php
      AddOutputFilter DEFLATE js
    </IfModule>
    

    To compress certain media-type use AddOutputFilterByType directive:

    <IfModule mod_deflate.c>
      AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript
    </IfModule>
    

    To enable compression for all documents use SetOutputFilter directive:

    <IfModule mod_deflate.c>
      SetOutputFilter DEFLATE
    </IfModule>
    
  • Dynamic way - using this way you can use complex boolean expressions.
    <IfModule mod_filter.c>
      FilterDeclare HttpHeaders
      <IfModule mod_deflate.c>
        FilterProvider HttpHeaders DEFLATE "%{HTTP:Accept-Encoding} =~ /gzip/ && %{CONTENT_TYPE} =~ m#^(application/javascript|text/css|text/html)#"
      </IfModule>
      FilterChain HttpHeaders
    </IfModule>

How to enable HTTP compression on nginx

Put the following code into the /etc/nginx/nginx.conf

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_http_version 1.1;
gzip_types text/html text/plain text/css text/javascript application/javascript;

How to enable HTTP compression with PHP

You can use PHP as alternative to compress your web pages with the help of zlib extension.

  • ob_gzhandler - intended to be used as a callback function for ob_start() to help facilitate sending gz-encoded data to web browsers that support compressed web pages.
    if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) {
        ob_start('ob_gzhandler');
    } else {
        ob_start();
    }
    
  • zlib.output_compression - transparently compress pages. Set this option to "On" in php.ini or Apache configuration (httpd.conf or .htaccess). You cannot use both ob_gzhandler() and zlib.output_compression. Also note that using zlib.output_compression is preferred over ob_gzhandler().
  • gzencode - the function creates a gzip compressed string.
    <?php
    $data = implode("", file("bigfile.txt"));
    $gzdata = gzencode($data, 9);
    $fp = fopen("bigfile.txt.gz", "w");
    fwrite($fp, $gzdata);
    fclose($fp);
    ?>
    
The numbers can't be wrong
Library Size Compressed size Compression ratio
react.js 627 KB 142 KB 77.3%
react.min.js 132 KB 39 KB 70.4%
font-awesome.css 32.5 KB 6.8 KB 79.0%
font-awesome.min.css 26.8 KB 6.5 KB 75.7%

The difference in sizes between compressed and uncompressed resources can be seen at the Size column of the Network tab in Chrome Developer Tools.
HTTP compression

Conclusion

Remember that enabling of gzip or brotli compression for text-based assets as scripts, styles and documents, reduce their size and improve website performance. And avoid to compress images, because they are already compressed.

Editor's Note: This post was originally published in February 2016 and has been revised and updated for accuracy and comprehensiveness.

Make your website more secure by using the HTTP Headers for Wordpress, and never face a cross-origin issue again. Oh yes, it's FREE.
See also
References
Share this post

If you have question about HTTP compression, leave a comment below. And do not forget to share this article. Thanks so much for reading!


3 Comments

sS
Hi Dimitar, unfortunately SetOutputFilter DEFLATE is deprecated. Maybe you can write some entry talking about mod_filter. Greetings.
Dimitar Ivanov
I just updated the article with an example of Dynamic filtering using the mod_filter.
sS
Great Dimitar, I'll check it!

Comments are closed