Click here to Skip to main content
15,888,610 members
Articles / Programming Languages / Javascript
Tip/Trick

How to Add JS Version before Referencing JS File to the Page

Rate me:
Please Sign up or sign in to vote.
4.47/5 (6 votes)
1 Jun 2023CPOL1 min read 15.8K   5   3
Updating referenced scripts realtime
This article will guide users on how to immediately show the changes made in their assets after deployment without waiting for the cache to clear.

Introduction

We always encounter a problem when it comes to the latest code deployed on our servers. The page cached the JavaScript, thus making our updates on the scripts to not immediately take effect.

Background

The approaches below will give you an idea on how to make our pages know that there was already an updated version of the script and should be evaluated immediately by the page. We should also take into consideration the page' performance, that's why we will go to use the global localstorage for some of the approaches.

First Approach

This approach will be suitable for the page with code behind.

On the ASPX markup, reference your CSS or JS files like this:

HTML
<link rel="stylesheet" type="text/css" 
href="<%=AppendVersion("/Styles/myCSS.css")%>" /> 

On the ASPX code behind, add the following code:

VB.NET
Public Shared Function AppendVersion(ByVal filePath As String) As String 
        Dim fileInfo As FileInfo = New FileInfo(Current.Request.MapPath(filePath)) 
        Dim cacheVersion As String = fileInfo.LastWriteTime.ToFileTime.ToString 
 
        Return filePath & "?v=" & cacheVersion 
End Function

Second Approach

This approach will be suitable for the page without code behind. In addition, we are going to use the window localstorage. The snippet for detecting the local storage below was from Mathias Bynens from this article.

On the ASPX markup, add the script:

aspx
<script type="text/javascript"> 
//Start snippet detecting the global localstorage
var storage = (function() { 
      var uid = new Date, 
          storage, 
          result; 
      try { 
        (storage = window.localStorage).setItem(uid, uid); 
        result = storage.getItem(uid) == uid; 
        storage.removeItem(uid); 
        return result && storage; 
      } catch(e) {} 
    }());
//End of snippet

var cached = function(name,value) { 
   if(storage.getItem(name) != null){ 
      return (storage.getItem(name).indexOf(value) >= 0)? true : false ; 
   }else{return false;} 
}; 

var GetFile = function(path) { 
        return path.substring(path.lastIndexOf('/')+1); 
    }; 
var execScript = function (script) {
        //locally created function
        var newfunction = new Function(script);
        newfunction();
    };
function RefJSVersioning(objUrl){ 
    var req = new XMLHttpRequest(); 
    req.open('HEAD', objUrl, false); 
    req.send(null); 
    var headers = (Date.parse(req.getResponseHeader
                  ('Last-Modified'))/10000).toString().split('.')[0]; 
    var source = objUrl + '?' + headers; 
    var fn = GetFile(objUrl); 
    if (storage) { 
      if(storage.length > 0){ 
         if (!cached(fn + 'source',source)){ 
            req = new XMLHttpRequest(); 
            req.open('GET', objUrl, false); 
            req.send(null); 
            storage.removeItem(fn + 'source'); 
            storage.removeItem(fn + 'content'); 
            storage.setItem(fn + 'source', source); 
            storage.setItem(fn + 'content', req.responseText); 
            execScript(req.responseText); 
         }else{ 
            execScript(storage.getItem(fn + 'content')); 
         } 
      }else{ 
         req = new XMLHttpRequest(); 
         req.open('GET', objUrl, false); 
         req.send(null); 
         storage.setItem(fn + 'source', source); 
         storage.setItem(fn + 'content', req.responseText); 
         execScript(req.responseText); 
      } 
    } 
};  

</script>

How to use:

HTML
<script type="text/javascript"> 
    RefJSVersioning("/Scripts/myScript.js");
</script>

Screenshot of the script stored on Local Storage:

Image 1

This approach also works with pages displayed inside an i-frame.

Image 2

Reference

History

  • 31st July, 2014

    • Created article
  • 3rd June, 2023

    • Updated code to stop using eval() because it is consuming a lot of memory
    • Added new function execScript
    • Updated header value for precise modified time. Instead of dividing with 100,000, it was changed to 10,000.
    • Updated screenshots on how to debug scripts from local storage

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Philippines Philippines
"Always debugging those undisputed bugs" Smile | :)

Comments and Discussions

 
NewsUpdated Script Pin
Junell Zenarosa27-Apr-15 20:07
professionalJunell Zenarosa27-Apr-15 20:07 
Thanks for the comments. I've already updated the code but forgot to update the screenshots for debugging.
Updates:
1) For using eval()
Updates:
- Created new execScript function which eventually do not use eval anymore.

2) For caching:
- if you examined carefully the code, there's a request type of 'Head' and 'Get'. The 'Head' doesn't load exactly the full xhr object. if we print out it's responseText it will return nothing. We just need the modified date to know if the javascript file was updated. So if it's still the same, it will just use the string saved on your local storage which only takes a milliseconds to retrieve. And if it's not the same, it will send another 'GET' request to retrieve the responseText and then save it locally.

But if still doesn't meet your requirements, you could actually tweak the code. The above code is just a tip on how to use the localStorage aside from caching.

BTW here's a fact:

What is the max size of localStorage values?

Quoting from the Wikipedia article on Web Storage:
Web storage can be viewed simplistically as an improvement on cookies, providing much greater storage capacity (5 MB per origin in Google Chrome, Mozilla Firefox, and Opera; 10 MB per storage area in Internet Explorer) and better programmatic interfaces.

And also quoting from a John Resig article [posted January 2007]:
Storage Space
It is implied that, with DOM Storage, you have considerably more storage space than the typical user agent limitations imposed upon Cookies. However, the amount that is provided is not defined in the specification, nor is it meaningfully broadcast by the user agent.
If you look at the Mozilla source code we can see that 5120KB is the default storage size for an entire domain. This gives you considerably more space to work with than a typical 2KB cookie.
However, the size of this storage area can be customized by the user (so a 5MB storage area is not guaranteed, nor is it implied) and the user agent (Opera, for example, may only provide 3MB - but only time will tell.)
GeneralMy vote of 1 Pin
Per Oestergaard5-Aug-14 2:38
Per Oestergaard5-Aug-14 2:38 
GeneralRe: My vote of 1 Pin
Junell Zenarosa5-Aug-14 20:41
professionalJunell Zenarosa5-Aug-14 20:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.