This leads to a common problem, though: if we make edits to a website’s files, how will the browser know to request the new version instead of loading the old, cached version? As long as the edited file has the same filename, the browser can’t tell the difference between the new version and the old one, which means users will see the old version of your code instead of the latest and greatest. :(
Note: Cache busting via query string is not the best solution because some proxy caching services don’t cache files with query strings. The best way is to change the filename itself. Changing filenames, however, involves changing server configurations, so that’ll require a little more work than just appending query strings. You can read more about this from web performance guru Steve Souders and this thorough StackOverflow answer.
We need a way to tell the browser to download only the files that have been edited and load the cached versions for all the other unchanged files. A quick way to do this without changing server configurations is to append a query string to the filenames wherever the files are loaded into your website (e.g. in the
<head>). In a
<script> tag, it could look like this:
<script src="filename.js?v=VersionNumberGoesHere"></script>. Every time you edit a file, you change
VersionNumberGoesHere to something new.
First, let’s make a file called
index.html.in. This will serve as the template Make will uses to produce the final
This Makefile will generate the script block to replace
Most of the action happens in the Makefile, and it involves 2 steps:
(1) In the
.make-script-block target, we first empty the content of
.make-script-block. Next, for each file in the
JS variable, calculate the file’s MD5 checksum and store it in a variable called
checksum. Then echo out the script tag and append the checksum as a query string and write the entire line to a file called
.make-script-block. End the for loop.
(2) Then we go to the
index.html target. The
sed utility searches
index.html.in for a pattern matching
%ASSETS% and replaces that pattern with the contents of
.make-script-block, which should be a file consisting of checksum’d script tags. The result is written into a file called
make index.html and you’ll have your new script tags. By using checksums we ensure that a file’s query string will only change if the file has been changed and that the query string will be relatively unique between updates. If the file hasn’t been touched since last make, then its query string remains the same and the browser will load the cached version instead of re-downloading it.
Hope this helped! Ask any questions in the comments. I’d be happy to explain things and/or help track down answers. :)