How To Achieve Maximum Website Performance (Part 4)

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.

Well, this still is an HTTP request that is sent to your server. Just think about how often you change images, CSS and JavaScript files on your server. Every 2 minutes?

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.

Cache Headers

This is the HTTP response header sent to your browser when you access this blog:

Live HTTP Headers Addon For Firefox showing headers

Live HTTP Headers Addon For Firefox showing headers (German version)

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:

$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

WARNING!

Never set the last two headers if the page you are using it on contains user-specific data. This means: if you offer a login on your homepage don’t add the last two lines as this may result in proxies between your server and the visitor’s PC storing this data so that another person who is using the same proxy might see confidential data belonging to the other user - “public” says it all in the code above. In all other cases you can normally safely  use the code as shown above. Just modify the cache time to suit your needs.

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!

Read the next part.

tweetthis-15

Share and Enjoy:
  • DZone
  • del.icio.us
  • Digg
  • StumbleUpon
  • Mixx
  • TwitThis
  • Technorati
  • FriendFeed
  • Google Bookmarks
  • BlinkList
  • blogmarks
  • Furl
  • LinkArena
  • Live
  • MySpace
  • NewsVine
  • Ping.fm
  • Reddit
  • Simpy
  • Spurl
  • Identi.ca
  • LinkedIn
  • MisterWong
  • Slashdot
  • Sphinn
  • Yahoo! Bookmarks
  • Facebook
  • RSS
  • Turn this article into a PDF!
  • Print this article!

Tags: , , , , , ,

Leave a Reply