Recommendations

PageSpeed
YSlow

YSlow: Add Expires headers

Overview

Expires headers let the browser know whether to serve a cached version of the page.

  • Reduce server load
  • Increase page load time
  • Cost benefit ratio: high value
  • Access needed
How does your site score on this recommendation?

What are expires headers

Expires headers tell the browser whether they should request a specific file from the server or whether they should grab it from the browser's cache.

The whole idea behind Expires Headers is not only to reduce the load of downloads from the server (constantly downloading the same file when it's unmodified is wasting precious load time) but rather to reduce the number of HTTP requests for the server.

When you visit a website your browser is responsible for communicating with the web server to download all the required files. It then compiles those files to display the web page. As web pages become richer in graphics and content, more and more files are being transferred between your machine and the web server.

In the past you would have an HTML file and maybe a few images to serve for your website, however many modern websites might have 50+ files per page to transfer. The files themselves can be a huge load increase by themselves but for each file you must create a request and even if requests are fractions of a second, they can soon add up.

How does it work?

Expires Headers are rather simple in how they work. They tell the browser how long to store a file in the cache so subsequent page views and visits they don't have to download the file again. You are right to assume Expires Headers don't improve page speed for a first time visit as this visitor would have to download all the files for the first time. Using Expires Headers helps increase load times for returning visitors.

You can set Expires headers on specific files or even file types. Then when the browser comes to the website it can see when was the last time it downloaded the specific file types. If it was recently it will display them from the cache, if you haven't visited the site in a while it will download the newest version from the web server.

The idea is to set late expiry times for items that don't change on your website (logo, colours etc). Set short expiry times for things that change regularly.

Why is it important?

Adding Expires Headers is important to reduce HTTP requests which reduces the time it take for the server to communicate with the browser. It also allows your users to reuse the cache files that have been stored in the browser to reduce the amount of files they need to download.

How to Add Expires Headers

First you need to decide on what files you update often and what file types don't get updated often. A common list of file types we see a lot are:

  • images: jpg, gif, png
  • favicon/ico
  • javascript
  • css

Now go through these file types and think how often you change each one. Commonly images typically are not changed too often (keep in mind we are talking about existing images) favicon is almost never changed, javascript is occasionally changed and CSS is change much more frequently.

We define our Expires Headers in the .htaccess file. This is a hidden file often found in the root of your website (via FTP). It's always best practice before you edit the htaccess file to back it up!

Now, open up your htaccess file and paste in the following:

<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On 
# Default directive
ExpiresDefault "access plus 1 month"
</IfModule>

First we enable expirations and then we set a default expiry date for files we don't specify. Now we want to add the lines to explain what expires when. Right above the </IfModule> paste the following and change the dates to reflect the times that best suit your website.

# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"

Your complete file should look like:

<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On 
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>

Summary

Server
High
Easy
26%

YSlow recommends:

There are two aspects to this rule:

  • For static components: implement "Never expire" policy by setting far future Expires header
  • For dynamic components: use an appropriate Cache-Control header to help the browser with conditional requests

Using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser's cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache. (A "primed cache" already contains all of the components in the page.)

Browsers (and proxies) use a cache to reduce the number and size of HTTP requests, making web pages load faster. A web server uses the Expires header in the HTTP response to tell the client how long a component can be cached. This is a far future Expires header, telling the browser that this response won't be stale until April 15, 2010.

Expires: Thu, 15 Apr 2010 20:00:00 GMT

If your server is Apache, use the ExpiresDefault directive to set an expiration date relative to the current date. This example of the ExpiresDefault directive sets the Expires date 10 years out from the time of the request.

ExpiresDefault "access plus 10 years"

Keep in mind, if you use a far future Expires header you have to change the component's filename whenever the component changes. At Yahoo! we often make this step part of the build process: a version number is embedded in the component's filename, for example, yahoo_2.0.6.js.

Using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser's cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache. (A "primed cache" already contains all of the components in the page.) We measured this at Yahoo! and found the number of page views with a primed cache is 75-85%. By using a far future Expires header, you increase the number of components that are cached by the browser and re-used on subsequent page views without sending a single byte over the user's Internet connection.

Read More

Related PageSpeed Recommendations