We'll delve into cache specific settings like Cache-Control HTTP header and configuration additions for various different server managing systems like Apache, Nginx, or PHP and hopefully clear up any confusion about this issue.
Before we get into the details of the matter, we should probably start with what can caching actually do for us. We can use HTTP caching to speed up the web page loading process on repeat visits. Whenever a repeat visitor comes to your site, their browser will use files from local cache to populate the website with resources, instead of fetching them from the server again. Furthermore, this will improve the webpage load speed and consequently improve the user experience for your visitors.
However, there are a few conditions for a resource to be cacheable
- It needs to be a static file, for instance a font, image, media file, script or stylesheet
- It has to return a HTTP status code 200, 203 or 206 on request
- It doesn’t have an explicit no-cache policy
How to cache static resources
In order to set up caching for your static resources, you’ll need to configure your server to return the Cache-Control HTTP header. This is a general header field we can use to specify directives or instructions for both requests and responses to control caching in browsers and shared caching like CDNs.
While multiple directives are permitted, we should focus on the max-age. This directive tells the caching mechanism how long it should store or cache a copy of a certain file. The following definition demonstrates an example of setting a max-age instruction for Cache-Control header, which accepts an integer number of seconds.
Cache-Control: max-age=31536000
The example above sets the cache duration for 1 year. But you should be aware of a risk that long cache durations pose, which is that your visitors won’t be able to see the updates you make to those static files that get cached. You can avoid this issue by configuring your bundling tool to embed a hash in your static asset filenames. This way your files will be unique to each version, which will prompt the user’s browser to fetch the newest version from the server instead of recalling the old version.
Moreover, we can set this header in a few different ways. We’re going to demonstrate how to do it for Wordpress, Apache, Nginx, and with PHP here.
Wordpress
Add the following example to .htaccess, but customize it for your needs.
## Leverage Browser Caching in WordPress via .htaccess ##
<IfModule mod_expires.c>
FileETag MTime Size
AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
ExpiresActive On
ExpiresByType text/html "access 600 seconds"
ExpiresByType application/xhtml+xml "access 600 seconds"
ExpiresByType text/css "access 1 month"
ExpiresByType text/javascript "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## Leverage Browser Caching in WordPress via .htaccess ##
Apache
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$">
Headerset Cache-Control "max-age=84600, public"
</filesMatch>
Nginx location
~* \.(js|css|png|jpg|jpeg|gif|ico)${expires2d;add_headerCache-Control "public, no-transform";}
PHP
header('Cache-Control: max-age=86400');
CDN services (e.g. Cloudflare)
If you use a CDN service, you should be able to set custom headers from their dashboard as well. However, you should avoid storing personalized contents on a shared cache, because it’ll store a single response to reuse it for multiple users. For personalized content, you should use browser cache.
How to check for cached responses
You can verify whether a resource is being cached or not, by using Chrome DevTools. More specifically, you can navigate to the Network tab and check the Size column, where cached resources will be fetched from either a memory cache or a disk cache. Moreover, storing in the memory cache is appropriate for the most requested resources, which will make them load really fast, but will be cleared once the user closes their browser. You can also check the Cache-Control header for each resource by clicking on it and navigating to the Headers tab.
Conclusion
To conclude, we talked about what HTTP caching is, how to implement it and how to check if it’s being applied. Moreover, we discussed what kind of content belongs in a shared cache and what in a browser cache. By using these tips, you’ll be able to setup an efficient caching for static files that PageSpeed insights tool warns you about.