How To Improve Website Speed By Enabling GZip Compression

How to improve website speed, performance and loading times by enabling output compression, either in Apache or via a PHP script.

By Tim Trott | PHP Tutorials | December 22, 2013
1,455 words, estimated reading time 5 minutes.
Search Engine Optimisation

This article is part of a series of articles. Please use the links below to navigate between the articles.

  1. SEO Strategy - Search Engine Optimization Tips in 2024
  2. A Guide to the Robots.txt Exclusion Protocol
  3. What Are XML Sitemaps and Why Do You Need One?
  4. How to Use Google Search Central (formerly Google Webmaster Tools)
  5. Google Analytics for Tracking Website Visitor Statistics
  6. How to Start Earning Money with Google Adsense in 2024
  7. Website Loading Times Are Vital - How to Improve Your Performance
  8. How To Improve Website Speed By Enabling GZip Compression
  9. How to Leverage Google Trends for Effective Keyword Research
  10. Top 8 Best Free Search Engine Optimization Websites & Tools

An important factor for fast-loading pages is serving compressed web pages, and Google has long stated website speed will impact search rankings. So how do you go about improving your website speed?

There are two ways that you can improve website speed by enabling compression for your generated content.

The first method works for static content, such as HTML and CSS, while the second only works on pages served generated with PHP. The third option is to use Brotli which is better than GZip but a lot more involved in setup and configuration and cannot be done on all web servers.

Testing GZip Output Compression
You can Improve Website Speed and save bandwidth by enabling compression

htaccess GZip Compression to Improve Website Speed

The simplest method for enabling GZip compression uses the Apache module mod_gzip which is available on most hosting platforms. Mod_gzip allows you to use the Gzip compression method to create a significant reduction in the volume of web page content served over the HTTP protocol.

If mod_gzip has not been installed on your server, and you have access to install modules, you can use this tutorial to install mod_gzip .

Once installed, enabling GZip compression is as easy as adding a few lines to the .htaccess file.

<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

If mod_gzip is not available, you can use the alternative mod_deflate which generally comes along with the Apache package.

To enable mod_deflate simply add these lines to your .htaccess file.

<ifmodule mod_deflate.c>
AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript
</ifmodule>

GZip Compression to Improve Website Speed with PHP

PHP can easily compress generated content before sending it to the browser and works in the same way as I described a few years ago when I wrote about compressing JavaScript and CSS files.

The preferred method for enabling compression in PHP is to set the zlib.output_compression variable in php.ini

Name Default Changeable Changelog
zlib.output_compression "0" PHP_INI_ALL Available since PHP 4.0.5.
zlib.output_compression_level "-1" PHP_INI_ALL Available since PHP 4.3.0.
zlib.output_handler "" PHP_INI_ALL Available since PHP 4.3.0.

If you can't update your php.ini configuration file, you could try using ini_set php function.

php
<?php
ini_set("zlib.output_compression", "On");
?>

Another option you can use is to use PHP's output buffering functions.

php
<?php
function print_gzipped_page()
{
    global $HTTP_ACCEPT_ENCODING;
    if( headers_sent() )
    {
        $encoding = false;
    }
    else if( strpos($HTTP_ACCEPT_ENCODING, 'x-gzip') !== false )
    {
        $encoding = 'x-gzip';
    }
    else if( strpos($HTTP_ACCEPT_ENCODING,'gzip') !== false )
    {
        $encoding = 'gzip';
    }
    else
    {
        $encoding = false;
    }

    if($encoding)
    {
        $contents = ob_get_contents();
        ob_end_clean();
        header('Content-Encoding: '.$encoding);
        print("x1fx8bx08x00x00x00x00x00");
        $size = strlen($contents);
        $contents = gzcompress($contents, 9);
        $contents = substr($contents, 0, $size);
        print($contents);
        exit();
    }
    else
    {
        ob_end_flush();
        exit();
    }
}
ob_start();
ob_implicit_flush(0);

/ Do your PHP awesomeness here
echo 'Hello World';

/ finally, call this function to send the compressed page
print_gzipped_page();
?>

Improve Website Speed with Brotli Compression with GZip Fallback

Brotli is a relatively new general-purpose lossless compression algorithm that compresses data faster and more efficiently than gzip. It offers significantly better compression ratios and thus smaller file sizes.

To use this it must be installed on the server. If you are on a managed hosting provider you can ask them to install it, if you manage your server then you can use these commands to install brotli.

powershell
sudo apt-get install brotli
sudo a2enmod brotli
sudo a2enmod deflate

On certain Linux distributions mod_deflate automatically enables gzip compression once installed and enabled. To use brotli we need to delete the config it created and it will revert to brotli.

powershell
rm -f /etc/apache2/mods-enabled/deflate.conf

Now all that is left is to configure the brotli output compression in the .htaccess.

apache
# Static Brotli:
# Browser accepts brotli, and matching pre-compressed file exists => rewrite to .br file
# For each file format set the correct mime type (otherwise brotli mime type is returned) and prevent Apache from recompressing the files
# Not sure why mime is necessary, but that's how Apache docs mention this.
RewriteCond %{HTTP:Accept-encoding} br
RewriteCond %{REQUEST_URI} .*\.(css|html|js|svg)
RewriteCond %{REQUEST_FILENAME}.br -s
RewriteRule ^(.+) $1.br
RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli,E=no-gzip]
RewriteRule "\.html\.br$" "-" [T=text/html,E=no-brotli,E=no-gzip]
RewriteRule "\.js\.br$" "-" [T=application/javascript,E=no-brotli,E=no-gzip]
RewriteRule "\.svg\.br$" "-" [T=image/svg+xml,E=no-brotli,E=no-gzip]
 
# Static Gzip:
# Browser accepts gzip, and matching pre-compressed file exists => rewrite to .gz file
# For each file format set the correct mime type (otherwise brotli mime type is returned) and prevent Apache from recompressing the files
# Not sure why mime is necessary, but that's how apache docs mention this.
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_URI} .*\.(css|html|js|svg|)
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz
RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-brotli,E=no-gzip]
RewriteRule "\.html\.gz$" "-" [T=text/html,E=no-brotli,E=no-gzip]
RewriteRule "\.js\.gz$" "-" [T=application/javascript,E=no-brotli,E=no-gzip]
RewriteRule "\.svg\.br$" "-" [T=image/svg+xml,E=no-brotli,E=no-gzip]
 
<FilesMatch "\.(css|html|js|svg)\.br$">
    # Correct the encoding type
    # Let proxy cache brotli & non-brotli separately
    Header set Content-Encoding br
    Header append Vary Accept-Encoding
</FilesMatch>
<FilesMatch "\.(css|html|js|svg)\.gz$">
    # Serve correct encoding type
    # Let proxies cache gzip & non-gzip files separately
    Header set Content-Encoding gzip
    Header append Vary Accept-Encoding
</FilesMatch>

# Dynamic Brotli:
<IfModule mod_brotli.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css
        AddOutputFilterByType BROTLI_COMPRESS application/x-javascript application/javascript application/ecmascript text/javascript application/javascript application/json
        AddOutputFilterByType BROTLI_COMPRESS application/rss+xml
        AddOutputFilterByType BROTLI_COMPRESS application/xml
        AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
        AddOutputFilterByType BROTLI_COMPRESS application/x-font-ttf application/vnd.ms-fontobject image/x-icon
    </IfModule>
</IfModule>
 
# Dynamic gzip:
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
        AddOutputFilterByType DEFLATE application/x-javascript application/javascript application/ecmascript text/javascript application/javascript application/json
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE image/svg+xml
        AddOutputFilterByType DEFLATE application/x-font-ttf application/vnd.ms-fontobject image/x-icon
    </IfModule>
</IfModule>
 
#Now some content won't benefit from brotli, like already pre-compressed content,
#So let us not bother with it
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp)$ no-brotli no-gzip dont-vary
 
# Make sure proxies don't deliver the wrong content
# It would be better of course if AddOutputFilterByType would allow us to set env, but whatever.
Header append Vary Accept-Encoding env=!dont-vary

It's a big section of code so let's have a look in detail.

The first sections, static brotli and static gzip will look for the file URL requested by the browser and see if there is a static brotli or gzip file, so if you request intex.html, it will first look for index.html.br then index.html.gz. Serving static compressed files is MUCH faster as the server doesn't have to do any work.

If the static files are not found then we hit the dynamic sections where the server will compress the requested file each time it is requested. This is slower than static compression so if your platform supports generating these static files then it should be enabled. If you're using WordPress plugins such as WP-Super-Cache and W3 Total Cache should support this for you.

Conclusion

Using any one of these methods should result in faster website download speed, but you still need to have an optimised high-performance website, to begin with. If your page takes 10 seconds to generate, all the Gzipping in the world isn't going to improve site performance unless you use static compression as described in the brotli section.

Once implemented, you should test your website loading speeds and see if compression is enabled to ensure that it working correctly. There are numerous sites  that can do this for you.

Was this article helpful to you?
 

Related ArticlesThese articles may also be of interest to you

CommentsShare your thoughts in the comments below

If you enjoyed reading this article, or it helped you in some way, all I ask in return is you leave a comment below or share this page with your friends. Thank you.

There are no comments yet. Why not get the discussion started?

We respect your privacy, and will not make your email public. Learn how your comment data is processed.