Enabling Caching and Gzip Compression with .htaccess

Your website’s speed and performance is paramount to keeping your visitors engaged. Slow loading web pages are devastating for businesses, resulting in the loss of a huge amount of potential sales and conversions.

The negative impact of a slow loading website is greatly magnified when browsing on a mobile device with a poor internet connection, so it’s essential that you reduce your web page load times. Luckily, there are many ways to improve your website’s speed, but I’m going to go over one of the simplest and easiest methods that will have a notable and positive impact on your site’s page speed – a .htaccess file.

Using a .htaccess file, we can enable the following performance features on an Apache web server:

  • Compression – Compresses the files on your server, so the browser downloads smaller files.
  • Caching – Caches files that are downloaded by the browser for a certain length of time, so the same files aren’t downloaded again unnecessarily when browsing a web page which uses those same files.

Creating a .htaccess file

The first step is to create a .htaccess file. To do this, start a new file in a text or code editor and save it in your website’s root directory (where your index file is) as ‘.htaccess’ – don’t use any other names or file extension formats, as it won’t work otherwise.

Enabling compression

With your .htaccess file open in your text editor, copy and paste the code below into it:

– Compression Gzip via Deflate

First thing to do, enable Gzip compression of output files from your server.

This will speed up the loading time, and reduce the bandwidth used. Be careful, however, because this compression is not supported by all browsers (including Netscape) and will only work on Apache 2.x servers. So test your site on several browsers after the implementation of this code.

# Compression Gzip via Deflate
<IfModule mod_deflate.c>
    # Compress text, HTML, JavaScript, CSS, XML
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/x-font
    AddOutputFilterByType DEFLATE application/x-font-opentype
    AddOutputFilterByType DEFLATE application/x-font-otf
    AddOutputFilterByType DEFLATE application/x-font-truetype
    AddOutputFilterByType DEFLATE application/x-font-ttf
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE font/otf
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE image/x-icon
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml

    # The following lines are to avoid bugs with some browsers
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    
    # Do not cache if these files are already cached
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
	
	# Proxies must give the right content
	# Header append Vary User-Agent env=!dont-vary
    Header append Vary User-Agent
</IfModule>

This enables Gzip compression of all the MIME types defined after the DEFLATEattribute. Above is the most common file formats for the web.

– Compression Gzip via Mod_Gzip

The following code replaces the previous one, but works on apache 1.x servers that can not handle the mod_deflate (well, or something like that) …

# Compression Gzip via Mod_Gzip
<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>

Enabling Browser Caching

Copy and paste the code below into your .htaccess file:

# Enabling Browser Caching
<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                    "access plus 1 month"
    
    # DATA
    ExpiresByType text/xml                            "access plus 0 seconds"
    ExpiresByType text/html                           "access plus 0 seconds"
    ExpiresByType text/plain                          "access plus 0 seconds"
    ExpiresByType application/xml                     "access plus 0 seconds"
    ExpiresByType application/json                    "access plus 0 seconds"
    ExpiresByType application/rss+xml                 "access plus 1 hour"
    ExpiresByType application/atom+xml                "access plus 1 hour"
    ExpiresByType text/x-component                    "access plus 1 hour"
    
    # MANIFEST
    ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
    ExpiresByType text/cache-manifest                 "access plus 0 seconds"
    
    # SCRIPTS
    ExpiresByType text/css                            "access plus 1 month" 
    ExpiresByType text/javascript                     "access plus 1 month" 
    ExpiresByType application/javascript              "access plus 1 month" 
    ExpiresByType application/x-javascript            "access plus 1 month" 
    
    # IMAGES
    ExpiresByType image/gif                           "access plus 1 month"
    ExpiresByType image/png                           "access plus 1 month"
    ExpiresByType image/jpe                           "access plus 1 month"
    ExpiresByType image/jpg                           "access plus 1 month"
    ExpiresByType image/jpeg                          "access plus 1 month"
    ExpiresByType image/jp2                           "access plus 1 month"
    ExpiresByType image/pipeg                         "access plus 1 month"
    ExpiresByType image/bmp                           "access plus 1 month"
    ExpiresByType image/tiff                          "access plus 1 month"
    ExpiresByType image/svg+xml                       "access plus 1 month"
    ExpiresByType image/vnd.microsoft.icon            "access plus 1 month"
    
    # ICONS
    ExpiresByType image/ico                           "access plus 1 month"
    ExpiresByType image/icon                          "access plus 1 month"
    ExpiresByType text/ico                            "access plus 1 month"
    ExpiresByType image/x-ico                         "access plus 1 month"
    ExpiresByType image/x-icon                        "access plus 1 month"
    ExpiresByType application/ico                     "access plus 1 month"
    
    # AUDIO
    ExpiresByType audio/ogg                           "access plus 1 month"
    ExpiresByType audio/basic                         "access plus 1 month"
    ExpiresByType audio/mid                           "access plus 1 month"
    ExpiresByType audio/midi                          "access plus 1 month"
    ExpiresByType audio/mpeg                          "access plus 1 month"
    ExpiresByType audio/x-aiff                        "access plus 1 month"
    ExpiresByType audio/x-mpegurl                     "access plus 1 month"
    ExpiresByType audio/x-pn-realaudio                "access plus 1 month"
    ExpiresByType audio/x-wav                         "access plus 1 month"
    
    # VIDEO
    ExpiresByType video/ogg                           "access plus 1 month"
    ExpiresByType video/mp4                           "access plus 1 month"
    ExpiresByType video/webm                          "access plus 1 month"
    ExpiresByType video/x-msvideo                     "access plus 1 month"
    ExpiresByType video/mpeg                          "access plus 1 month"
    ExpiresByType video/quicktime                     "access plus 1 month"
    ExpiresByType video/x-la-asf                      "access plus 1 month"
    ExpiresByType video/x-ms-asf                      "access plus 1 month"
    ExpiresByType x-world/x-vrml                      "access plus 1 month"
    
    # FONTS
    ExpiresByType font/truetype                       "access plus 1 month"
    ExpiresByType font/opentype                       "access plus 1 month"
    ExpiresByType application/x-font-ttf              "access plus 1 month"
    ExpiresByType application/x-font-woff             "access plus 1 month"
    ExpiresByType application/font-woff               "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject       "access plus 1 month"
    
    # FLASH
    ExpiresByType application/x-shockwave-flash       "access plus 1 month"
    ExpiresByType video/x-flv                         "access plus 1 month"
    
    # OTHERS
    ExpiresByType application/pdf                     "access plus 1 month"
    ExpiresByType image/vnd.wap.wbmp                  "access plus 1 month"
    ExpiresByType application/vnd.wap.wbxml           "access plus 1 month"
    ExpiresByType application/smil                    "access plus 1 month"

    <IfModule mod_headers.c>
        Header append Cache-Control "public"
        <FilesMatch "\.(ico|flv|jpg|jpeg|png|gif|css|swf)$">
            Header set Cache-Control "max-age=2678400, public"
        </FilesMatch>
        <FilesMatch "\.(html|htm)$">
            Header set Cache-Control "max-age=7200, private, must-revalidate"
        </FilesMatch>
        <FilesMatch "\.(pdf)$">
            Header set Cache-Control "max-age=86400, public"
        </FilesMatch>
        <FilesMatch "\.(js)$">
            Header set Cache-Control "max-age=2678400, private"
        </FilesMatch>
    </IfModule>
    
</IfModule>

This is enables browser caching for all MIME types defined after the ExpiresByTypeattribute.

Using the mod_expires module, we can define how long each file type gets cached for after we’ve defined it’s MIME type. In the example above, you’ll see that some of the file types have “0 seconds” cache time, this is because some of the files shouldn’t be cached such as HTML and text – any changes made to the copy on a website should be immediate, so we don’t cache them. Others like CSS and images will change less frequently, so we can cache them for longer periods of time.

What next?

Once you’ve saved your .htaccess file, the server will now be serving compressed files and browsers will caching certain files too, giving your website a much needed speed boost! But using a .htaccess to compress and cache your files is just the tip of the iceberg for web performance improvements.

Additional performance gains can be found by serving images that are appropriately sized for a device’s viewport and optimizing all of your images using ImageOptim or similar. You should also look at minifying your Javascript and HTML files, and combining multiple Javascript and CSS files into one to reduce the amount of HTTP/S requests.

Resources