Welcome to the fourth part of the article series on how to maximize the performance of your website. This time I will show you how you can minimize the number of HTTP requests to your server by setting appropriate cache headers so that the browser does not request the file time and again while a visitor is browsing your site.
5. Caching And Expiration
Most of the people think that if a browser has downloaded a file like an image or CSS file from the server it has stored it in the cache directory on the local harddisk and will retrieve it from there without sending a new request to the server every time it is embedded in an HTML page.
However this is simply not true. Modern browsers just like Firefox or Internet Explorer 7 will most of the time send an “If-Modified-Since” request to the server to find out if the file has been updated on the server. This is good because your browser can use the file from the cache if it has not changed on the server without downloading the file again.
Most of the time your answer to that question will simply be “No.” although this makes sense for some specific files like images from a webcam that may be updated every few seconds.
This is the HTTP response header sent to your browser when you access this blog:
Let’s examine the different headers in detail:
Expires: Wed, 11 Jan 1984 05:00:00 GMT
This tells your browser that the file has already expired so that the browser should retrieve from the server again next time it is requested.
Cache-Control: no-cache, must-revalidate, max-age=0 Pragma: no-cache
These headers tell the browser that it must not cache the file and always has to revalidate if the file on the server has been updated.
Last-Modified: Sun, 10 May 2009 18:06:04 GMT
When looking at the headers of static files like images you will often see a header like this which is the file modification time.
Time To Optimize
So now let’s optimize the header settings for some of our files. This optimization assumes that you are using the Apache web server. If you do not have root level access to your web server you cannot use this optimization as described here, regretfully. There are other ways which I am planning to write about in a later post.
First of all you need access to your webserver configuration. You need to add the Expires module (“mod_expires”) to your Apache configuration file httpd.conf like this where all the other lines beginning with LoadModule are located at the beginning of the file:
LoadModule expires_module modules/mod_expires.so
This will load the Expires module into your Apache web server. Now you need to add the following lines to your VirtualHost configuration – the VirtualHost given is only an example – just add the <IfModule>…</OfModule> block to your existing VirtualHost block for the domain you wish to speed up.
<VirtualHost 127.0.0.1:80> ServerName example.com DocumentRoot /srv/www/example.com/htdocs CustomLog /logs/example.com.access_log combined <IfModule expires_module> <Location /flvplayer.swf> ExpiresActive On ExpiresDefault "access plus 1 day" </Location> <Location /img> ExpiresActive On ExpiresDefault "access plus 2 hours" </Location> </IfModule> </VirtualHost>
This example code assumes that you want all of the files in the /img directory to be cached on the client side for two hours and the file /flvplayer.swf to be cached for one day. You can add as many <Location> blocks as you wish. There are several options available you can look up on the Apache website.
By using this method Apache will add the appropriate HTTP headers automatically.
Setting Manual Headers In Your PHP Files
You can also set expiration and caching headers automatically in your PHP files. By default as PHP is a language where the code is interpreted at runtime PHP sends an Expires header with a date long gone. Here is some example code:
1 2 3 4 5 6 7
$cacheTime = 60*60; // 1 hour header("Expires: " . gmdate("D, d M Y H:i:s", gmmktime() + $cacheTime)." GMT"); header("Pragma: public"); // HTTP/1.0 header("Cache-Control: public, max-age=".(int)$cacheTime.""); // HTTP/1.1
How To Find The Perfect Cache Time Value
You should resist the temptation to set the expiration for all of your files to one day or anything more than a few hours. Just imagine you have an image on your website which shows a product with the price next to it. If you change the price when the user returns to your website several hours later (which may depend on your business) he will not be able to see the updated price because the original file has not yet expired in his browser’s cache.
I suggest using several different values depending on how often specific content changes. Your company logo for example is unlikely to change every day (unless you are Google, of course) so you may set a high value here. Just remember that you can (OK, should be able to) change the value on your server at any time so if you are planning to update some images you may as well lower the value a few days or hours before the change is scheduled to happen.
There is no rule of thumb so you just have to think about the different types of files and how often you update these files.
This concludes this article. I appreciate your comments below – feel free to retweet!