Using an enqueued file’s modified time to break the browser cache

If you’ve been a web developer for a while you’ve likely uttered the phrase, “Empty your cache,” or “Hold shift and click reload” to a user not seeing some of your newly-published changes. When you tell a client to take a look at some revisions, you want them to see the newest version of the site, obviously. But, for performance reasons, browsers will very often cache CSS stylesheets and JavaScript, storing them on the user’s disk or in memory, to more quickly load a site. A trip to a computer’s hard drive for a cached copy of a file is much quicker than grabbing a copy over the network. And CSS and JavaScript files are not going to change too often on most websites.

Using your web browser’s Web Inspector, you can see what assets are cached and what assets are being transferred over the Internet. Open up your Web Inspector now and choose the Network tab. Hit reload and view the “Size” column in the results. Many items will, as you would expect, display the size of that item. For example, a PNG file might be displayed as 9.7kB. Some items, though, won’t display a Size at all. Instead of a size, they will display the cache they were grabbed from, the memory or disk cache. Here is an example from this website:

Examples of resources loaded from the network and from caches.

One thing that you will probably notice are the very low Times needed to load items from the cache. This really helps to speed up the loading of a page.

Now look at the Name column. You will note that many files have a version appended to them. jQuery is loaded is as jquery.min.js?ver=3.5.1 (at least as of the composing of this post). The version is used to tell the browser when an asset has changed. If a browser has jQuery 3.5.0 cached, and sees a new version like the one above, it will know that the cached version of the file is out-of-date and that a new copy needs to be pulled down from the network.

I should take a moment to note that your server configuration makes a difference here. A server can be set up to or not to cache elements. I am not going to discuss configuration of a server to cache assets but, for more details, read this Google article about HTTP Cacheing.

With the knowledge that a browser will take a look at the version of a file, and reload it if changed, we can set a version number with WordPress’s enqueue functions. A stylesheet can be loaded on your site using WordPress’s wp_enqueue_style function. One of the parameters of the wp_enqueue_style function is $ver. You could hardcode the $ver and just change it whenever you make modifications to your stylesheet. If you had:

wp_enqueue_style( 'theme-style', get_template_directory_uri() . '/inc/assets/dist/css/style.css', null, '1.0.0' );

Then the appended version for the stylesheet would be “1.0.0”. Verify this by using the Web Inspector’s Network tab.

Changing the wp_enqueue_style‘s version:

wp_enqueue_style( 'theme-style', get_template_directory_uri() . '/inc/assets/dist/css/style.css', null, '1.0.1' );

Would append ?ver=1.0.1 to the loaded CSS file.

You’ll likely not want to hardcode the version number, though. You will forget to change it. And you don’t want the extra work. What we could do, is take the last time that the CSS file was changed, and use that for a version. Then, every time the timestamp of the file is changed, the appended version will change as well and a fresh copy will be loaded to the user’s browser.

PHP has a filemtime function to determine when file has been changed. I personally use filemtime in conjunction with PHP’s date function to make it a little more readable. Since I know where my theme’s CSS file is located, I can get a date of when it was last updated using the following code:

$css_ver = date( "ymd-Gis", filemtime( get_stylesheet_directory() . '/inc/assets/dist/css/style.css' ) );

Resulting in a $css_ver value of 210104-210229. I find having a readable date allows me to quickly look at the version number in my source code and see if the version, indeed, has been updated properly. The above tells me straight away that the file was updated on January 4th, 2021.

To complete the final step, we can use our retrieved $css_ver in WordPress’s wp_enqueue_style function as the $ver value.

wp_enqueue_style( 'fairmount-style', get_template_directory_uri() . '/inc/assets/dist/css/style.css', null, $css_ver );

Changes made to the CSS file should now update the version of our CSS file and, thus, tell the web browser to grab a fresh copy of the file from the server because the version of the cached file will be different than our latest version.

Leave a comment

Your email address will not be published. Required fields are marked *