Summary: Easy site speed optimization can be done with simple .htaccess rules. These rules make any website faster by compressing the data and using browser cache.
I've done a post about .htaccess rules before, but I wanted to make a simplified version for those who don't need all the technical details of .htaccess. Now this is as simple as it gets, and here are the step-by-step instructions...
Here's what you need
- Access to the .htaccess -file at the root of your own domain
- self-hosted website
- Good hosting service which supports compression
- preferably via mod_deflate, not mod_gzip
- Enough technical skills for simple file management
- via cpanel or FTP for example
- 2 minutes to check that your host supports proper compression
- this is somewhat tricky part, but I walk you through it
- 15 seconds to edit the .htaccess -file
- copy & paste
Here's what you get
- Faster (and more secure) website
- Better user experience for your visitors
It doesn't matter if you run a tiny website, an eCommerce site or a blog, these .htaccess rules will work and make your site faster. From Yahoo's expeptional performance guidelines (Best practices for improving web page performance), we rock these:
Site speed optimization is not about getting the grade A with YSlow, but making your website faster. The guidelines are good, that's why I help you and your website to follow them.
Here's what you need to do
Two steps.
- testing that your host has enabled proper modules for compression.
- adding the .htaccess rules.
1. Verify that compression is enabled
If you know that your host has mod_deflate -compression enabled, you can skip this first part. If you're thinking: "mod_defl_what?", don't worry - you don't need to know, just follow the instructions...
1.1: Create a temporary directory to your server, e.g. http://example.com/temp/
1.2: Create two files into that directory
(or create the files locally, then transfer to the directory)
1.2.1: Create index.shtml.txt -file into the temp-directory with one line
(#printenv inside a html comment):
<!--#printenv -->
1.2.2: Create a new .htaccess -file into the temp-directory with these lines:
SetEnv MOD_mod_deflate 0
SetEnv MOD_mod_gzip 0
SetEnv MOD_mod_headers 0
SetEnv MOD_mod_expires 0
<IfModule mod_deflate.c>
SetEnv MOD_mod_deflate 1
</IfModule>
<IfModule mod_gzip.c>
SetEnv MOD_mod_gzip 1
</IfModule>
<IfModule mod_headers.c>
SetEnv MOD_mod_headers 1
</IfModule>
<IfModule mod_expires.c>
SetEnv MOD_mod_expires 1
</IfModule>
(don't add these to your root .htaccess -file!)
1.2.3: Access the index.shtml.txt file with your browser
For example: http://example.com/temp/index.shtml.txt - if you have problems, make the file index.shtml instead, and access the directory, e.g. http://example.com/temp/
1.2.4: Look for MOD_* from the index.shtml.txt -page. If all is perfect, you'll find deflate, headers and expires as 1 (enabled), like this:
MOD_mod_deflate=1
MOD_mod_gzip=0
MOD_mod_headers=1
MOD_mod_expires=1
(there will be plenty of data on that page, but these are the ones we care about)
In case deflate, headers and expires are not all enabled (1), or you have mod_gzip instead of mod_deflate, the htaccess rules below need to be modified a bit, and here's some help for that:
- If you have both mod_headers and mod_expires, the rules below can be used as is, and you'll get full benefit of browser and proxy caching.
- If you're missing mod_headers or mod_expires, the rules require tweaking. For that, check one of my references: how to use caching and Cache-Control (with just mod_expires or mod_headers, or both).
- (if you don't have mod_deflate, all is not lost, see below for "Alternative solutions")
1.3: You can delete the temporary (temp) directory afterwards.
Now that you know if your host has mod_deflate enabled, you can move on to adding the rules to the .htaccess -file...
2. Backup the original .htaccess file
- Copy the .htaccess to your local drive or take a copy of it as .htaccessold or such
- If anything goes wrong with adding the new rules, return the backed-up .htaccess -file
- There should not be any danger, but to save any trouble later, just take the backup
3. Add the .htaccess rules
- Find the .htaccess -file at the root of your domain (e.g. public_html), and add the rules into the file.
- If the .htaccess -file is not there, create it. Make sure you name the file .htaccess ("dot htaccess").
- If you create and edit the file on your computer, make sure the file does not have any hidden extension like .txt in the file.
- If you're running a WordPress blog, make sure the WordPress default rules are at the bottom of the .htaccess file.
.htaccess rules are case sensitive! Make sure you copy-paste the rules as they are (and double-check if you write your own rules).
Antti's WordPress .htaccess rules
The rules work for non-WordPress sites as well (any website actually), but these are especially awesome for speeding up a WordPress blog.
### BEGIN .htaccess
# Protect the htaccess file
<Files .htaccess>
Order Allow,Deny
Deny from all
</Files>
# Protect wpconfig.php
<Files wp-config.php>
Order Allow,Deny
Deny from all
</Files>
# Disable directory browsing
Options All -Indexes
# BEGIN COMPRESSION AND CACHING
<IfModule mod_deflate.c>
# Enable compression
AddOutputFilterByType DEFLATE text/css text/javascript application/x-javascript text/html text/plain text/xml image/x-icon
<IfModule mod_setenvif.c>
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
</IfModule>
<IfModule mod_headers.c>
# Make sure proxies deliver correct content
Header append Vary User-Agent env=!dont-vary
# Ensure proxies deliver compressed content correctly
Header append Vary Accept-Encoding
</IfModule>
</IfModule>
<IfModule mod_headers.c>
# No ETags, No Pragma
Header unset Pragma
Header unset ETag
# Default cache time to 1 year (31536000 sec)
Header set Cache-Control "max-age=31536000, public, must-revalidate"
</IfModule>
# No ETags
FileETag none
# CACHE SETTINGS (mod_expires)
<IfModule mod_expires.c>
# Turn on Expires
ExpiresActive On
# set default to "access plus 1 year"
ExpiresDefault A31536000
# html - "modification plus 1 hour"
ExpiresByType text/html M3600
# css and JavaScript - "modification plus 6 weeks"
ExpiresByType text/css M3628800
ExpiresByType text/javascript M3628800
ExpiresByType application/x-javascript M3628800
</IfModule>
# No cache for php-files
<FilesMatch "\.(php)$">
<IfModule mod_expires.c>
ExpiresActive Off
</IfModule>
<IfModule mod_headers.c>
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
</IfModule>
</FilesMatch>
# END CACHING
# W3 Total Cache are here (automatically included by the plugin):
# WordPress Default Rules are here (at the end of the file):
### END .htaccess
When you have the rules in the .htaccess -file, you're done!
Customizing the Expires Header times
With longer cache time, you should change the filename everytime you modify something (which is somewhat difficult with WordPress theme styles, which always use style.css for example, thus the shorter cache for css).
Similar tweaks can be done to other values and filetypes as well. For detailed info, you can consult Apache module mod_expires documentation or ask me for configuration suggestions via mail and the comments.
Why use 3 minutes on this?
With these .htaccess rules in place, you have
- More secure site (with .htaccess -file and directories protected)
- Compressed components for faster loading times
- Browser cache leverage for even faster site for returning and recurring page visits
You only have to edit the .htaccess -file once and you're set.
- Use this simple HTTP Compression test to check that the compression is active.
- For a bit more geeky testing, to get full Header information, etc. use this GZip test or this GZip checker.
Alternative solutions
Can't access .htaccess
Can't access or upload .htaccess? You need a self-hosted website. If your hosting provider does not allow editing/using .htaccess, consider moving to one of the better hosting providers.
No mod_deflate?
If you see MOD_mod_gzip, but not MOD_mod_deflate, here's the other post of mine with good mod_gzip htaccess rule ("6.2. Using mod_gzip Compression") you can use instead of mod_deflate (it won't be as good, but go with what you got.
No mod_gzip either?
If you have somehow ended up using a hosting provider that sucks, a host that doesn't support mod_deflate (OR at least mod_gzip), I strongly suggest you move your site to one of the better hosting providers before you build your site any further.
It is possible to compress content via PHP, but if a host does not have mod_deflate or even mod_gzip enabled, their service is just not good. Compression uses CPU, and poor hosting services save (incorrectly) by not allowing to use it in any way.
Of course, before you move, make sure that you did the above steps correctly, and also verify from the tech support that the host does not mod_deflate or mod_gzip - and you can always contact me and I'll see if I can help.
Own or Virtual Private Server?
If you run your own server, or virtual private server, you have more control into these matters, and might need to enable the services, like mod_deflate, yourself. Also, in this case, you have access to advanced website performance optimization techniques, not available on shared hosting, like adding the rules in the httpd.conf instead of .htaccess, PHP opcode cache (aka PHP accelerator), etc.
Comments? Improvements?
Publish, then polish. These rules are result of my obsessed research, tests, trial & error. Endless hours of running speed tests, going through logs, checking the website with YSlow and Page Speed -plugins, checking headers, compression data and much more.
If you know and find a better way to do this, you should tell me about it, so I can check, test and update these rules. So, if you know how to make these even better, or just have something to ask, I'd love to hear about it...
If you have any questions or feedback, leave a comment to this post or contact me via email.
Updates:
2010-08-16: new and improved .htaccess rules added. the rules are now safe for everyone, if corresponding module is not enabled on host, the rules are simply ignored. no more Internal Server Error 500s anymore.
Summary
Step-by-step site speed optimization via .htaccess rules:
- Check that your host supports compression via mod_deflate, and mod_expires + mod_headers are enabled.
- Edit the root .htaccess -file by adding the set of rules
- Enjoy your properly cached and compressed content delivering, much faster website!
.htaccess is just one way to speed up your WordPress blog or improve website performance in general. Stay tuned for more WordPress speed tricks and site speed optimization tips: Get the RSS feed or subscribe via email to get the updates delivered to you.
Antti Kokkonen
Jedi Knight of .htaccess rules
Join the WordPress Speed Challenge to speed up your WordPress blog and make it load a lot faster!