HTTP Caching Headers

Posted on: December 5, 2015 by Dimitar Ivanov


An important part of building a top notch web app or website is its performance. Nowadays speed is everything. High performance websites ranks better at SERP and have a lower bounce rate. Using the browser cache to load static resources will boost the performance of your web page. Next benefits are easy measurable:

  • Reduce web page load time
  • Reduce HTTP requests on subsequent visits
  • Reduce web page size
  • Reduce server load
  • Reduce server bandwitch

Cache-Control Header

Dynamically driven content such as text/html documents usually is not cached. That's the default behavior of web servers.

HTTP Cache-Control Header
Figure 1. HTTP Cache-Control Header

But when it's about static resources as images, styles, scripts, etc. they should leverage browser caching using the cache-control header. Various directives of cache-control header are available:

  • public
  • private
  • no-cache
  • no-store
  • no-transform
  • must-revalidate
  • proxy-revalidate
  • immutable
  • max-age
<FilesMatch "\.(js|css|jpe?g|png|gif)$">
  <IfModule mod_headers.c>
    Header set Cache-Control "public, max-age=31536000, immutable"

Expires Header

Use an Expires header for static resources as images, styles and scripts. Adding a far feature expires headers in server response tells the browsers(web-proxies) to cache the resource for specific amount of time, and load it from the browser's cache if available, on subsequent loading of the web page. This technique leads to significantly reduce of the web page load time as well as server load reduce. If the browser cache is empty you can't expect the benefits of an expires headers yet.

If you use a far future expires headers do not forget that you must change the name of resource after a change in its content. Usually this is achievable by including the version/timestamp in the file name main-2.1.js. Depending of configuration web-proxies does not cache a resources with querystring in their filenames. So its better to avoid using querystring in the resource filename main.js?v=2.1.

Let's see how to configure expires headers for Apache web-server using a .htaccess file.

  • Enables generation of Expires headers

    This directive enables the generation of the Expires and Cache-Control headers.

    ExpiresActive On
  • Default algorithm for calculating expiration time

    This directive defines the default algorithm for calculating the expiration time for all documents. Later you will see how to override it.

    ExpiresDefault "access plus 10 days"
  • Value of the Expires header configured by MIME type

    This directive defines the value of the Expires header and the max-age directive of the Cache-Control header generated for documents of the specified type (e.g., image/png).

    ExpiresByType image/png "access plus 1 year"
  • All above together

    It's a good idea to enclose the directives into an IfModule directive. Thus way you will avoid HTTP Status 500 in case the mod_expires module is not turned on.

    <IfModule mod_expires.c>
      ExpiresActive On
      ExpiresDefault "access plus 10 days"
      ExpiresByType text/css "access plus 1 year"
      ExpiresByType text/plain "access plus 1 year"
      ExpiresByType image/gif "access plus 1 year"
      ExpiresByType image/png "access plus 1 year"
      ExpiresByType image/jpeg "access plus 1 year"
      ExpiresByType image/x-icon "access plus 1 year"
      ExpiresByType application/x-javascript "access plus 1 year"
      ExpiresByType application/javascript "access plus 1 year"
      ExpiresByType application/x-icon "access plus 1 year"
HTTP Expires Header
Figure 2. HTTP Expires Header

ETag Header

Entity tags (ETags) are used by servers and browsers to determine whether the resource from browser's cache match the version on the server. The problem is that ETags won't match when the resource from browser's cache tries to validates on the server who is not the same one who gives the resource for first time. That's the case of large scale websites using clustered hosting solutions to provide high availability service. So if you prefer to use only cache-control and expires header, you should remove the ETag header.

<IfModule mod_headers.c>
  Header unset ETag
FileETag None

At last when you know how important is http caching for high performance and you are in process of applying your preferred cache policy, use Chrome DevTools, Firefox Developer Tools or Headers Inspector to analyze the HTTP headers of your web page.

Make your website more secure by using the HTTP Headers for Wordpress, and never face a cross-origin issue again. Oh yes, it's FREE.
See also
Share this post

For more thoughts about high performance stay tuned at @DimitarIvanov. If you have questions about the http caching headers, please leave a comment below. Thanks so much for reading!


Comments are closed