How to Specify a Cache Validator

What is a cache validator?
A cache validator is defined within HTTP request and response headers and help determine if it is still valid to retrieve a file from the browser's cache. Cache validators are important as they determines whether or not your request must be sent to the server (thus increasing load times and expending resources) or if the files can be retrieved directly from local cache therefore improving load times and decreasing latency.
Retrieving previously requested resources directly from the browser's cache is always more efficient than making a request to the server which creates additional round trips. When you specify a cache validator, such as a Last-Modified
or ETag
header, this helps ensure browsers are taking advantage of caching as efficiently as possible.
Cache validation example
The following example shows how you can determine that cache validators are being used. The first step is to navigate to a web page and then open the developer tools window. In Chrome, this can be done by right clicking on the page and selecting inspect element. Next, navigate to the Network tab and refresh the page. You will see a list of various assets that are used to create the web page. If this is the first time you are visiting the page or if you perform a hard reload on the page you will receive a 200
status code for your asset which means the request was successful.
However, upon reloading the same page, this asset now returns a 304 Not Modified
status as it was previously retrieved from the server and is now stored in the browser's cache.
After the first request, the browser knows that the last time this file was modified was on April 16 2015 at 10:26:33 GMT. Now on subsequent requests, the browser sends the If-Modified-Since
HTTP header to check if this information differs from the Last-Modified
header date/time.
Another method of cache validation includes using an ETag
which provides a revalidation token sent by the browser to check if the resource has changed since the last time it was accessed. The browser then includes the If-None-Match
header within a request which the server will check to see if both tokens match.
The differences and similarities between the If-Modified-Since
and If-None-Match
headers are explained in further detail in our 304 Not Modified
article.
How to specify a cache validator
Web servers such as Apache, Nginx, etc. include the Last Modified header by default. In order to satisfy the specify a cache validator suggestion from a page speed test tool such as GTmetrix, either the Last-Modified
or ETag
and Expires
or Cache-Control
headers are required. The Last-Modified
and ETag
headers help the browser determine if the file has changed since the last time it was requested while the Expires
and Cache-Control
headers determine how long the file should be held in cache before it fetches a new copy from the server.
Without any Cache-Control
or Expires
headers the browser would not know how long it should keep a local cached copy before retrieving a new one. These header may already be defined on your server, however the following snippets provide examples on how to manually define them in Apache and Nginx.
Apache
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Header set Cache-Control "max-age=84600, public"
</filesMatch>
Nginx
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 2d;
add_header Cache-Control "public, no-transform";
}
Additionally, If you want to add a Last-Modified
header directly within a dynamic file, this can be achieved using the PHP gmstrftime
function, for example:
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
In some instances if you are loading resources from other domains, you will receive a notice from site speed tests to specify a cache validator for these resources. This notice can be safely ignored as with assets loaded from fonts.googleapis.com
for example, as you have no control on setting the cache validator, which may be removed intentionally anyway.
Ensuring that you specify a cache validator and that it is working properly in conjunction with either the Expires
of Cache-Control
headers is important for ensuring that you are taking full advantage of browser caching and speed improvements.