Whenever we do some modification to the existing .js and .css files and move them to a production environment, those changes may not get reflected in the browser of the customer who is using our software. This is because those .css and .js files have been cached in the browser. When the user accesses the URL, it will take the cached .js and .css files. That is the reason those new changes will not appear to the user. The user either has to clear the browser cookie & reload the page or else he or she has to do a hard refresh of the page by pressing Ctrl+F5.
But, we cannot ask each and every user to clear the cookie of their browser. We cannot even ask them to go for a hard refresh of the page. So, we can hack this through an approach called Cache Busting.
Cache Busting
It is a unique string appended to the path of the .js file or .css file in the form of a query string.
Ex: /jsScripts/myUpdates.js?v=1
When a webpage is downloaded, then its associated files are also downloaded and stored in the browser's cache on the user’s machine.This has to happen as this process improves the performance where the page doesn't need to download these associated files again and again whenever the page is refreshed.
Now, there can be an issue with this process. Whenever we do some changes to any of the existing .js or .css files and update the production environment, the client's browser may not be able to get to see upon refreshing the page as it has cached those files during previous page refresh. As a developer, we need to ensure that client's browser should get these updates in existing files without much struggle.
Therefore, cache buster query string can be updated so that the browser doesn't recognize the file in the cache memory and downloads the new file on a refresh of the page.
When to use this mechanism
Do not do for all .js, .css files in your solution package. Analyze which files often get modified and apply a cache busting mechanism only to those files. Because caching is essential for performance point of view. For every refresh of the page, if all of its associated .js, .css files get downloaded, then it will decrease the performance. Hence, select only a few files which often get modified.
Different types of cache busting
Static Cache busting
When a file is updated, all references to that file could be manually updated to increment sof version numbers such as 1, 2, 3, etc. But this is not an ideal approach as we need to do lots of manual work to change version number every time we modify the file.
- Ex: /jsScripts/myUpdates.js?v=1
- Ex: /jsScripts/myUpdates.js?v=2
- Ex: /jsScripts/myUpdates.js?v=3
You can use today's date and time through javascript
I endorse this approach as it helped me from a deployment and code management perspective.
Suppose, I have done some changes today and upgraded the site offline when the client is not using the site. Assume that the client has used the site yesterday and if I append today's date and time as a query string to the path of the file, then it searches for the file with query string equal to today's date and time when the client has loaded the page. Since it doesn't recognize the file in the cache, then it will download the file from the server, hence the user can see the latest version of file.
Here, the user doesn't need to go for a hard refresh through ctl+f5 or deleting the cookie.
Inside the <head> tag load all those files which you think get updated more often.
- <script type="text/javascript" language="javascript">
- var versionUpdate = (new Date()).getTime();
- var script = document.createElement("script");
- script.type = "text/javascript";
- script.src = "/myProduct/scripts/myUpdates.js?v=" + versionUpdate;
- document.body.appendChild(script);
- </script>
In the above example, I have created a variable under the script tag and get a datetime value. I am loading a .js file (I am assuming I have to do changes in this file more often) and passing versionUpdate value as a query string value at the end of the path.
Note that, in the above snippet, I have done DOM manipulation rather than using document.write (Script_path_with_query_string); , because document.write is a bad practice and you should try to avoid it.