Apache – setting header expires via apache config
html header expires
Setting html header expires can help speed up your website. They work by telling your browser to cache various elements of a webpage for a period of time. These include scripts, images, css & so forth. So if you use the same stylesheet throughout the whole of your website, you can specify how long the cached version stays valid. This reduces the number of http requests made to your server thus reducing the overall time it takes to load your page.
Lets get started
Important note: If you are already specifying a header expire directly in your web page, ie html or php files, apache mod_expires will obey these rules and will not supersede them. Just to bear in mind just in-case you think the mod_expires is not working for you.
How do you know if expires are being set?
To check by default, analyse the response header sent to your browser by your server. I use Firefox, Firebug & the YSlow plugin to view page headers:
HTTP/1.1 200 OK
Date: Sat, 02 Mar 2013 20:12:00 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Sat, 02 Mar 2013 19:53:12 GMT
Cache-Control: max-age=86400
Expires: Sun, 03 Mar 2013 20:12:00 GMT
Content-Type: text/html
You will see an “Expires” field in your header. As you can see, this particular page was initially fetched on 02 Mar 2013 20:12:00 GMT and Expires on 03 Mar 2013 20:12:00 GMT
This is approximately 1 day , defined by Cache-control: max-age=86400 (86400 is seconds)
Hopefully, you too at the end of this tutorial will see the Expire field in your header.
Prerequisites
Ensure mod_expires is enabled. There are many google tutorials out there specific to your setup, in my setup I use a debian based server (ubuntu), you can use this command to enable mod_expires for apache:
sudo a2enmod expires
Enable & Setup expires
Edit your websites apache conf file. For instance
sudo nano /etc/apache2/sites-available/yoursite.com
Example apache config:
<VirtualHost *:80> ServerName www.yoursite.com DocumentRoot /var/www/yoursite <Directory /var/www/yoursite/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> </VirtualHost>
Add the following line to enable expires for your site:
ExpiresActive On
Your config should now look like this:
<VirtualHost *:80> ServerName www.yoursite.com DocumentRoot /var/www/yoursite <Directory /var/www/yoursite/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all ExpiresActive On </Directory> </VirtualHost>
This tells apache to enable expires for your site – but we are not done! Now we want apache to tell the web browsers that we want to cache the page being served for a specified period of time. To do this we simply use the following directive:
ExpiresDefault "access plus 1 day"
ExpiresDefault will enable caching for all the static content served by the server
Your config should now look like this:
<VirtualHost *:80> ServerName www.yoursite.com DocumentRoot /var/www/yoursite <Directory /var/www/yoursite/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all ExpiresActive On ExpiresDefault "access plus 1 day" </Directory> </VirtualHost>
Reload your apache configs or restart apache server:
sudo service apache2 reload or sudo service apache2 restart
Once apache has reloaded configs or restarted, browse to your website using Firefox, open the YSlow plugin via Firebug and click “Run Test.
Once the test has been completed, within YSlow click on the tab “Components” to view if Expires have been set:
If you look at the Expires column, you can see that the Server has sent a header with the Expires field set to 1-day. This tells the browser not to download these files again until they have expired after a day.
Setting Expires for specific content
In most cases you do not want to set the same Expires period for all your static content. For example, website graphics are unlikely to change in one day – so you may want to drill down and specifically tell the browser not to fetch new images unless 30 days have passed. You can do this very easily by utilising ExpiresByType directive. This lets you target a specific mime type, for example, you want to set Expires for jpeg/jpg images only for 30 days:
ExpiresByType images/jpg "access plus 30 days"
ExpiresByType images/jpeg "access plus 30 days"
However this can be problematic because a the file itself may change, i.e you had to update the logo. If you set expires to 30 days, the user will not see the new logo unless they clear their browsers cache or use CTRL+F5 to refresh all the content manually.
In this instance you will want to use the “modification” setting instead of “access”:
ExpiresByType images/jpg "modification plus 30 days"
ExpiresByType images/jpeg "
modification
plus 30 days"
This will tell the browser not to download the Logo unless 30 days have expired OR the Logo file was modified.
If you do not want to manually create ExpiresByType directive for each file type, you can group them instead using apache’s powerful <filesmatch> regex directive:
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"> ExpiresActive On ExpiresDefault "access plus 1 day" </filesMatch>
With this in place, apache will only enable and set Expires for the files matched. You can also use this method to disable ExpiresActive for various types if you have set it globally.
See below for a complete apache config that I use on my developer server that works:
<VirtualHost *:80> ServerName www.yoursite.com DocumentRoot /var/www/yoursite <Directory /var/www/yoursite/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all ExpiresActive On ExpiresDefault "access plus 1 day" <filesMatch ".(ico|jpg|jpeg|png|gif)$"> ExpiresActive On ExpiresDefault "access plus 30 day" </filesMatch> <FilesMatch ".(txt|xml|js|css)$"> ExpiresActive On ExpiresDefault "access plus 1 day" </FilesMatch> </Directory> </VirtualHost>
For more information about using mod_expires, please visit http://httpd.apache.org/docs/2.2/mod/mod_expires.html
Happy Caching!
MANY hours of searching today, this was the most straight forward how-to. Thank you.