Table of Contents
Step 1. Enable Drupal's page cache
Enable Drupal's page cache if you haven't already. For anonymous visitors this will reduce HTML page build times by 90%. Pages served from the cache are automatically compressed without any further configuration changes.
Step 2. Don't use PHP's output handler compression
PHP supports optional "obj_gzhandler" and "zlib" output handlers that can automatically compress all data sent from a PHP program. Unfortunately, both of these have problems with Drupal's page cache.
When Drupal sends a compressed page from it's page cache, it correctly marks the page with a "
Content-Encoding: gzip" page header. From then on, any software that handles the page should recognize that the page is compressed. Unfortunately, both of the PHP output handlers ignore this header and mistakenly compress the output a second time. When the doubly-compressed result is shown in a web browser, it's a garbled mess.
Since PHP's output handlers can't be configured to work properly, don't use them. Disable them by editing your "php.ini" file. Set the "
output_handler" line to empty, and the "
zlib.output_compression" line to "
Off". On a new installation of PHP, these are the default values anyway.
zlib.output_compression = Off
Step 3. Enable an Apache compression module
Apache has two commonly-used compression modules: mod_gzip and mod_deflate. Both can be configured to work properly with Drupal.
Mod_gzip is free and available for Apache 1.x and 2.x. For Windows PCs, download the DLL file. For Linux PCs and Macs, download the source code and compile it. Installation instructions are included with the downloads. In each case, you'll drag the new module into Apache's module folder.
Next, edit your server's "httpd.conf" file, or your web site's ".htaccess" file to enable and configure the module (replace MODULE below with the path to the installed module).
LoadModule gzip_module MODULE
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_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
AddModule make the module available, and
mod_gzip_on turns it on. The
mod_gzip_dechunk line directs the module to collect all of Drupal's output before compressing any of it.
mod_gzip_item_include lines list file types to compress, while
mod_gzip_item_exclude lines list what not to. The last line directs mod_gzip to skip compressing files that Drupal has already compressed, such as those from it's page cache.
Mod_deflate comes pre-installed with Apache 2.x. To configure it, edit your server's "httpd.conf" file or your site's ".htaccess" file:
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
SetOutputFilter enables the module and
DeflateCompressionLevel sets the amount of compression from 1 (not much) to 9 (as much as possible). The
SetEnvIfNoCase lines block the module from compressing images, executables, and previously compressed files. Everything else gets compressed.
File size results
After adding and configuring a compression module, restart Apache. To confirm that compression is working you'll need to look at the HTTP response header sent from your web server back to your browser. This header isn't normally shown by browsers, so use the free Web Sniffer web site to show the header. You want to see a line like this:
Google's free Load Time Analyzer 1.5 extension for Firefox provides an easy way to show file sizes before and after enabling compression. Load a web page, then press the extension's "Graph" button to list the files loaded by the page, their sizes, how long each one took to load, and the order in which they were loaded.
The table below lists the files downloaded for the home page of our simple and complex test web sites (see Specifications for Drupal web site testing). The complex site has more modules enabled, so it includes more CSS and image files than does the simple site.
|Simple site (bytes)||Complex site (bytes)|
|Simple home page||17,805||4,229|
|Complex home page||29,471||6,086|
Load time results
Smaller files take less time to send. This is particularly important when the web site is served through a limited network connection, such as a cable modem or DSL. To measure compression's impact on load time, we simulated a cable modem's bandwidth limits by using the Charles proxy server to throttle network bandwidth down to the 64 Kbyte/sec typical of a cable modem. Loading a web page through the proxy server logs page sizes and download times. Compression reduced text file load times by 60-70%. Taking image files into account, compression reduced the total page load time by about 50%.
|Simple site (seconds)||Complex site (seconds)|
|Simple home page||4.538||1.251|
|Complex home page||7.912||2.866|
These tests temporarily disabled Drupal's page cache to measure size and load times of uncompressed and compressed HTML pages. Enabling the page cache shaves 1-3 seconds off the total page load time. While that is certainly good, the page load time is dominated by the time to load CSS and image files, neither of which are affected by Drupal's page cache. Also, the page cache only speeds up page delivery for anonymous visitors. Logged-in visitors will be served custom uncached pages with load times like those above.
What to do next
Measured page load times at cable modem speeds for our simple and complex test sites are still 8 and 11 seconds, respectively. This is way too high. For good usability, we need to be under 1 second.