Friday, September 6, 2013

Speed up a web site by enabling Apache file gzip compression

Setting up the server

The "good news" is that we can't control the browser. It either sends the Accept-encoding: gzip, deflate header or it doesn't.
Our job is to configure the server so it returns zipped content if the browser can handle it, saving bandwidth for everyone (and giving us a happy user).
For IIS, enable compression in the settings.
In Apache, enabling output compression is fairly straightforward. Add the following to your .htaccess file:

# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

# Or, compress certain file types by extension:
<files *.html>
SetOutputFilter DEFLATE
</files>

Apache actually has two compression options:
  • mod_deflate is easier to set up and is standard.
  • mod_gzip seems more powerful: you can pre-compress content.
Deflate is quick and works, so I use it; use mod_gzip if that floats your boat. In either case, Apache checks if the browser sent the "Accept-encoding" header and returns the compressed or regular version of the file. However, some older browsers may have trouble (more below) and there are special directives you can add to correct this.
If you can't change your .htaccess file, you can use PHP to return compressed content. Give your HTML file a .php extension and add this code to the top:
In PHP:
<?php if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start(); ?>
We check the "Accept-encoding" header and return a gzipped version of the file (otherwise the regular version). This is almost like building your own webserver (what fun!). But really, try to use Apache to compress your output if you can help it. You don't want to monkey with your files.

How to enable file compression

Apache 1.x and 2.x can automatically compress files, but neither one comes with a compressor enabled by default. Enabling compression reduces CSS, HTML, and JavaScript file sizes by 55-65% and speeds up overall page load times by 35-40%.
Apache uses plug-in modules to add functionality. For Apache 1.x, use the free mod_gzip module to compress files. For Apache 2.x, use mod_gzip or the built-in mod_deflatemodule.
Enable file compression using mod_gzip
The mod_gzip module can be used with Apache 1.x or 2.x, but it doesn’t come with either Apache distribution. You’ll need to download and install it separately.
  1. Windows:
    1. Log in to your PC using an account with administrator privileges.
    2. Download the zip file containing ApacheModuleGzip.dll from SourceForge.
    3. Unzip the file.
    4. Move ApacheModuleGzip.dll to your Apache modules folder (typically “c:\Program Files\Apache Group\Apache\modules”).
    5. Edit your server configuration file using a text editor like NotePad (typically “c:\Program Files\Apache Group\Apache\conf\httpd.conf”). Add the following line to your server configuration file as the last loaded module:
      LoadModule gzip_module modules/ApacheModuleGzip.dll
      Add the following lines to your server configuration file or to a site’s “.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>
  2. Mac:
    1. Log in to your Mac using an account with administrator privileges.
    2. Download the zip file containing the module’s C source code from SourceForge.
    3. Unzip the file.
    4. Compile the module using the included instructions.
    5. Move mod_gzip.so to your Apache modules folder (typically “/usr/libexec/httpd”).
    6. Edit your server configuration file using a text editor like TextEdit or vim (typically “/etc/httpd/httpd.conf”). Add the following line to your server configuration file as the last loaded module:
      LoadModule gzip_module libexec/mod_gzip.so
      Add the following lines to your server configuration file or to a site’s “.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>
                          
  3. Restart Apache.
The “LoadModule” line in the configuration file makes the module ready, while the other lines configure and enable it. Put these other lines in the server’s configuration file to affect all sites served by the web server. Or put them within a site’s “VirtualHost” block or in its own “.htaccess” file to affect only that site.
The remaining lines tell the module to compress files with .htm, .html, .txt, .css, .js, .php, and .pl file name extensions, the output of CGI scripts, and any output that is text or JavaScript, but not images. The last line tells the module to skip compressing content that is already compressed.

Enable file compression using mod_deflate

The mod_deflate module comes with Apache 2.x. All you need to do is enable it.
  1. Windows:
    1. Log in to your PC using an account with administrator privileges.
    2. Edit your server configuration file using a text editor like NotePad (typically “c:\Program Files\Apache Group\Apache\conf\httpd.conf”). Add the following lines to your server configuration file or to a site’s “.htaccess” file:
      <Location />
          SetOutputFilter DEFLATE
            SetEnvIfNoCase Request_URI  \
              \.(?:gif|jpe?g|png)$ no-gzip dont-vary
          SetEnvIfNoCase Request_URI  \
              \.(?:exe|t?gz|zip|gz2|sit|rar)$ no-gzip dont-vary
      </Location> 
  2. Mac:
    1. Log in to your Mac using an account with administrator privileges.
    2. Edit your server configuration file using a text editor like TextEdit or vim (typically “/etc/httpd/httpd.conf”). Add the following lines to your server configuration file or to a site’s “.htaccess” file:
      <Location />
          SetOutputFilter DEFLATE
          SetEnvIfNoCase Request_URI  \
              \.(?:gif|jpe?g|png)$ no-gzip dont-vary
          SetEnvIfNoCase Request_URI  \
              \.(?:exe|t?gz|zip|gz2|sit|rar)$ no-gzip dont-vary
      </Location> 
  3. Restart Apache.
Put the configuration lines in the server’s configuration file to affect all sites served by the web server. Or put them within a site’s “VirtualHost” block or in its “.htaccess” file to affect only that site.
The “SetOutputFilter” line enables the module.
The next two lines instruct the module to skip compressing image files (.gif, .jpg, .jpeg, .png), executables (.exe), and compressed files (.gz, .tgz, .zip, .gz2, .sit, .rar). Everything else gets compressed.

Verify Your Compression

Once you've configured your server, check to make sure you're actually serving up compressed content.
  • Online: Use the online gzip test to check whether your page is compressed.
  • In your browser: Use Web Developer Toolbar > Information > View Document Size (like I did for Yahoo, above) to see whether the page is compressed.
  • View the headers: Use Live HTTP Headers to examine the response. Look for a line that says "Content-encoding: gzip".

No comments:

Post a Comment