Serve Static Assets With An Efficient Cache Policy


What is a cache policy and how to set the right HTTP cache policy to serve your static files.






What it means?

When a browser requests a file, the server providing the file can tell the browser how long it should cache the file. If the user re-requests the file (by revisiting your site) in this duration, the browser can use the local copy instead of re-downloading it. In this way, HTTP caching helps load your pages faster for returning users.

Static assets refers to JS, CSS and image files. Since these files are not expected to change very frequently, HTTP caching should be setup for these. Since these are served by web servers (Apache, Nginx, etc) - the web server needs to be configured for this to work.

A server tells the browser about caching a file through a cache-control header. It looks like this:

Cache-Control: public, max-age=31536000

Here, the max-age is the time in seconds, for which the browser can use the local copy of the file instead of re-downloading it.

Setup Cache Policy For Nginx

If your website is served via Nginx web server, you can update it's configuration to enable adequate caching policy:

sudo vi /etc/nginx/nginx.conf

Here, you can add the cache control policy specific settings within the server block:

server {
	..
	location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
		expires 365d;
		add_header Cache-Control "public, max-age=31536000";
	}
}

Restart Nginx to ensure the new configuration is in action:

sudo systemctl restart nginx

Setup Cache Policy For Apache

If you use Apache2 Web Server to serve your website, you will have to update the .htaccess file within the website's root folder or the configuration file containing the addequate <VirtualHost> entry for your website:

<VirtualHost *:80>
        DocumentRoot (Your root folder here)
        ServerName (ServerName Details Here)
        ..
		<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|svg)$">
			Header set Cache-Control "max-age=31536000, public"
		</FilesMatch>
		..
</VirtualHost>

Restart your Apache web server for the new configuration to take effect:

sudo service apache2 restart

Why Cache Policy for Static Assets should not be set via PHP?

Your static assets (JS, CSS, Image files) are typically served via your web server (Apache, Nginx) and thus, cache policy for static files should not be set via PHP. However, you can definitely set HTTP headers (including cache policy headers) via PHP for specific PHP pages. However, PHP pages resources of your site are not static assets and their cache policy should be different from the one stated on this web page.

Verify Cache Policy in Action

To verify that your web server is returning the response with right cache control headers, you can use the curl command with -I flag (to view only HTTP response headers):

curl -I <YourStaticFileURLHere>

You should look for the 'Cache-Control' in the HTTP response header. If it is as below, your configuration is working as expected:

HTTP/1.1 200 OK
..
Cache-Control: max-age=31536000, public
..

HTTP Caching Gotchas

If you change the content of your static (CSS, JS, Image, etc) files due to any reason and if a returning user visits your site, the browser may show him (stale) cached file contents. To avoid this scenario, you should change the name of your static file everytime it's content changes. You can achieve this by adequate versioning or by appending last modified timestamp to the file name or through other similar mechanisms. Failure to do so may lead to broken / erronous website experiences.