Compressing Magento output

Compression is one of the tricks to gain performance with any website. So the same applies with Magento. However, the general rules that you can find on the Internet to compress output through Apache mod_deflate are very general, or even wrong when used in combination with Magento Downloadable Products.

The problem of Magento Downloadable Products

When you download a file through Magento as offered by a Downloadable Product, this file is not a direct download from the filesystem. Instead, the file is generated through the PHP-code of Magento - which offers security to protect your downloads from illegal access.

The problem here is that Magento is responsible for generating the right HTTP-headers. We found that with our webserver configuration, the HTTP-headers generated with Magento did not combine well with Apache mod_deflate and Internet Explorer. As soon as we turned on mod_deflate, Internet Explorer (and other browsers) was unable to download any ZIP-files offered as Downloadable Products.

Internet Explorer causes problems

The main problem with Internet Explorer is that if you apply wrong compression rules to your site, some files may be compressed twice - perhaps first through PHP-compression and next by Apache mod_deflate. This leads to the following Internet Explorer error:

The Compressed (zipped) Folder is invalid or corrupted.

Worse: Even if a ZIP-file (a compressed archive) is compressed again through Apache mod_deflate, Internet Explorer is unable to unpack it twice - ending up with the same error.

Do not compress everything!

Because of this Internet Explorer problem, the following mod_deflate rule is dead wrong and should never be applied:

SetOutputFilter DEFLATE

Compress only what you need

Because ZIP-files and images should not be compressed, the best practice is to only compress those things that you need to compress. The Apache directive AddOutputFilterByType allows you to deflate things only on content with the right MIME-type:

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
AddOutputFilterByType DEFLATE application/javascript application/x-javascript

Don't use application/x-httpd-php

We have come across examples where the MIME-type "application/x-httpd-php" was also compressed, but this actually stops your Magento Downloadable Products from working correctly. So do not include this MIME-type in your rules.

#AddOutputFilterByType DEFLATE application/x-httpd-php

Preparing for exceptions

The rules above work fine and should be sufficient for your Magento instance. However, sometimes images or movies might be generated through PHP. Consider the following an extra fail-safe check, which makes sure that media like images, videos, documents and archives are not compressed twice:

SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:pdf|doc)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:avi|mov|mp3|mp4|rm)$ no-gzip dont-vary

The full mod_deflate code

The following mod_deflate code which we found to be working very well can be found below. This code can replace the existing entry in the Magento .htaccess file:

<IfModule mod_deflate.c>

    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript
    AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml
    AddOutputFilterByType DEFLATE application/javascript application/x-javascript
    #AddOutputFilterByType DEFLATE application/x-httpd-php

    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.(?:pdf|doc)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.(?:avi|mov|mp3|mp4|rm)$ no-gzip dont-vary

</IfModule>

With this code, Magento should be much faster while keeping your Downloadable Products intact.