Browser Caching Reference

Verify the Website Implementation

Browser Caching Reference

by John Vincent

Posted on June 17, 2018

This is a discussion regarding browser caching.

For more website validation documentation, see Website Validation Reference

A useful resource, Web Fundamentals, HTTP Caching

Audit pages to identify which resources can be cached and ensure that they return appropriate Cache-Control and ETag headers.

Browser Caching

If Cache-Control: max-age = 0, the resource will not be cached.

To check browser caching

the tool will test for browser caching problems.

Browser caching problems are caused by incorrect server configuration.

Nginx Serving Static Resources

For Nginx configuration details, see Configure HTTPS Nginx

Check Nginx HTTPS Server Configuration. Ensure has

location ~*  \.(svg|jpg|jpeg|png|gif|ico|css|js|pdf)$ {
	expires 30d;


location ~*  \.(svg|jpg|jpeg|png|gif|ico|css|js|pdf)$ {
	add_header Cache-Control "max-age=31536000";
	access_log off;

or, at least cache the images.

Express Serving Static Resources


  • Chrome Tools
  • Network tab
  • Response Headers
    • cache-control: max-age

max-age = 0 => no caching.

If this value is not set properly, read on.

Note the static resources are being served from the Express server, not from Nginx.



app.use(express.static(path.resolve(__dirname, '../public')));
app.use('/assets', express.static(path.resolve(__dirname, '../public/assets')));


var options = {
	maxAge: '90d'
app.use(express.static(path.resolve(__dirname, '../public'), options));
app.use('/assets', express.static(path.resolve(__dirname, '../public/assets'), options));	

or whatever is a suitable value.

Check Browser Caching

In Chrome Developer Tools

  • Network tab
  • Disable Disable cache (top nav)
  • Enter URL

For each item that should be cached, check the Response Headers, for example

cache-control: max-age=2592000
content-encoding: gzip
etag: W/"5b4dxvwh-w6b692"
expires: Thu, 16 Aug 2018 14:56:18 GMT
last-modified: Tue, 17 Jul 2018 14:29:36 GMT
server: nginx
status: 200

and the Request Headers, for example

cache-control: no-cache
pragma: no-cache

etag value is sent to the server so that

  • The server uses the ETag HTTP header to communicate a validation token.
  • The validation token enables efficient resource update checks: no data is transferred if the resource has not changed.

"no-cache" indicates that the returned response can't be used to satisfy a subsequent request to the same URL without first checking with the server if the response has changed. As a result, if a proper validation token (ETag) is present, no-cache incurs a round-trip to validate the cached response, but can eliminate the download if the resource has not changed.

Ensure content-encoding: gzip as this makes a huge difference in download size and timing.

  • Size is the combined size of the response headers (usually a few hundred bytes) plus the response body, as delivered by the server.
  • Content is the size of the resource's decoded content. If the resource was loaded from the browser's cache rather than over the network, this field will contain the text (from cache).

Test Single Resource

Lets use a simple resource

First get

status = 200
timing = 50.96ms

Second get

status = 304
timing = 5.10ms

Test Website Page

Lets use

First get

All resources return

  • status = 200
  • lengthy downloads

Second get

All resources return

  • status = 200
  • size = (from memory cache) or (from disk cache)
  • downloads are generally 0ms