Client script caching in ASP.NET IIS application - javascript

I am currently testing a web site as the development goes on, and almost every time the client script is updated, I need to clear the browser cache for a new functionality to become available on the client due to the fact that the browser downloads the fresh compy of the .js file.
What if in production I roll out a new version of a script? How do I get the client browsers to get it as soon as it is uploaded to the server?
I am using an ASP.NET MVC 4 site.

Easiest way will be adding the version number to the script file(say script_1.6.js etc)

Rename the file to create versioning:
so
<script src="myscript.js"></script>
becomes
<script src="myscript-9-5-2012.js"></script>
Also per https://developers.google.com/speed/docs/best-practices/caching#LeverageProxyCaching
It's not recommended to use querystrings for versioning (ie. myscript.js?v=1.1.0) because specifically
Most proxies, most notably Squid up through version 3.0, do not cache resources with a "?" in their URL ...

The best way to stop your scripts from caching is to add a random querystring value at the end of each line. e.g.
<script src="/path-to-your-script/script.js?v=0b1"></script>
This is great in development as your scripts never get cached, although in production you do really want the browser to cache the scripts to speed things up.
So for production, you would probably want to introduce some versioning like jquery for instance, jquery-1.8.0.js

Related

How to purge browse cache - index.html stuck in cache

I have a ReactJS app hosted in S3 and using Cloudflare as DNS & CDN.
I have a huge issue, a lot of visitors have old version of the application stored in their browser cache (index.html only). I have configured advanced cache control in the newest version, but it cannot be accessed because older version is shown instead.
Static file (CSS, JS) versioning is done using create-react-app, but I have discovered that index.html file is the only cached one.
What should I do now?
How to purge visitors cache now?
PS: I have purged Cloudflare cache already and setup rule to bypass cache.
Unfortunately there is no such solution for this.
The only way is to wait until users cache will empty (expire).
It is technicaly impossible to clear users cache from external resource (JS script etc.), due to security reasons.
Also if it will be possible, there is no way how to tell users to download latest JS (including cache purging code), because they have old version of index.html (including link to those .js files).
You are stack and the only option is to wait.
A better approach would be, whenever your build changes, change the JS link so that the browser downloads the new version from the server, no matter the user's or the server's caching policy.
For example, the way Stack Exchange does it is, whenever the build changes, the HTML goes from something like:
<script src="https://cdn.sstatic.net/Js/stub.en.js?v=1bac371ac78f"></script>
to
<script src="https://cdn.sstatic.net/Js/stub.en.js?v=f83b2f654"></script>
Whenever there's a new build, you can randomize the parameter in the query string in the HTML, and still only have the single (most recent) built .js on your server.

AngularJS app hot reload in production

I am using AngularJS 1.5.8 to build the client side of my webapp. I have frequent problems because users don't have the last version of the webapp client side. Is there an easy way to perform hot angular app reloading, in order my users to always have the last version? (I am looking for an alternative of websockets)
You can poll your server from your client web-app by using setInterval() with an ajax call to some REST endpoint that is capable of returning the most recent version. If that version doesn't match, say, your "version" variable, then you force a reload of the application.
In your index.html file where you load in all your .js files, you can include a version number in the URL that you increment whenever you do a new build. This will force the user's browser to reload the library from your server as the URL won't exactly match, effectively breaking the cache mechanism and preventing old versions of your code from loading.
The additional data in the URL won't have any effect on the application otherwise.
<script src="js/app.js?v1.2.3"></script>
<script src="js/services.js?v1.2.3"></script>
<script src="js/filters.js?v1.2.3"></script>
<script src="js/directives.js?v1.2.3"></script>
<script src="js/components.js?v1.2.3"></script>
You would do a search/replace for v1.2.3 to v1.2.4 on the next build.
If you're using something like webpack, or some other build pipeline / automation tool, you can do this automatically by including the hash of the library in the file name, and then dynamically updating the URL in the index.html file. When you see files like app.ad76c09743ef.js, that's likely how that's being generated. This ensures that even a single character change in your source results in a new, unique hash that will prevent the browser from using an older cached value.
The library I have used for this to good success is https://github.com/saintmac/angular-cache-buster
Each time the user makes a request for a resources, it will force latest version it not on white list.

How can I ensure that the latest version of my javascript code is loaded for the client?

We have a client with thousands of users (who all use Internet Explorer) and a large amount of javascript files that enhance their user experience with our product.
The problem I'm having is that any time we update one of these scripts there is no way to know whether the client is seeing the latest version. What we're having to do is tell our client to do a hard refresh (ctrl+f5) before viewing any changes. Obviously this approach is not ideal.
I know that browsers cache based on the url, so one could use something like
<script src='myScript.js?ver=1.2'>
to get around the issue, but this is not an option for us.
I was hoping that there's some kind of header property or something similar that we could use to tell IE not to cache these scripts.
Any ideas?
You can also version the filename itself like jQuery does:
<script src='myScript-v1-2.js'>
Then, each time you revise the script, you bump the version number and modify the pages that include it to point to the name of the new script. This is foolproof vs. caching, yet still allows your viewers to receive the maximum benefit of caching and requires no server configuration changes for the .js file.
A full solution will typically include setting a relatively short cache lifetime for your host web page and then allow the various resources (stylesheet files, JS files, images, etc...) to have longer cache lifetimes for maximum caching. Anything that is fingerprinted can have a very long cache lifetime. See the reference that fabianhjr posted about for ways to set the cache lifetime of the host web page. It can be done in the web page itself (<meta> settings) or in the http headers via the server.
If you turn off caching for your script file (which would likely have to be done at the web server level for a script file) then all your viewers will lose the performance benefit of caching and you will lose the bandwidth and load-saving benefit of caching. If you use a common .JS file across many pages (a common design pattern), your viewers will see slower performance on every page.
Everything you need to know about cache http://www.mnot.net/cache_docs/
http://www.mnot.net/cache_docs/#CACHE-CONTROL <-- HTTP Headers

From where is it better to import a js file?

I would like to know which solution is the fastest and the best for my web pages between importing a javascript file from an external source and internally. Which pro and cons for each solution.
For example, which one is the best:
< script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
or
< script type="text/javascript" src="../jquery.js"></script>
(same for json2.js)
I could not find any tips on google
Thanks!
The main benefit of using a CDN (Content Delivery Network) is that given their widespread use, the chances are your visitor may already have a cached copy of the script you're trying to load on their browser. This will completely negate any loading time. If they don't have a cached copy, the chances are the CDN would deliver it to them faster than your server could anyway. In my opinion it's best to use a CDN where possible.
Even with that in mind, CDN aren't infallible, and you don't want your site to rely 100% on someone else's server. I'd advise on having a local copy of your scripts and use those as a backup where possible. For jQuery, this is quite easy:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src='/Scripts/jquery-1.7.1.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
Other libraries may vary in their methods for testing if they're loaded, but the idea is the same.
It's also worth noting that if you are loading from Google's CDN ALWAYS use the full version number otherwise the script will not be cached.
That is to say if your request URL looks like this:
"http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" // highest 1.4 version (1.4.4)
"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" // latest version (1.7.1)
The expires header is set previous to the current date, so the effect of caching is nullified.
More info on this here
If you import javascript from http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.jsimprove data access, Google has CDN that means deliver content more efficiently to users (depend on their location).
Read more about CDN:http://developer.yahoo.com/performance/rules.html
The fastest is definetely from your own server, at least in most cases(that is in pure download speed).
However, there is a much greater chance that a visitor has Google's version of jQuery already cached in their browser from visiting another site using the same library, and as such it probably makes more sense using the Google API for the most common libraries, as that would be much faster if the library is cached compared to having to download it from your server.
Also, these days you can do this, and request the version by just using the first number :
http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js
And automagicly get the latest version ;)
Using a CDN has some advantages:
If the user has already visited another site that uses the same script from the same location, they may have it in the browser cache already. The page loading speeds up when they don't have to re-download it.
The CDN provider probably has the server set up to maximize the efficiency of serving the scripts, for example by sending the file from a server physically closes to the user.
You save bandwidth.
The disadvantages:
You are dependent on the service provider: if their service is down, your site breaks. (This can be helped by serving a local copy of the file if the external script couldn't be loaded.)
You have to trust the service provider for serving the correct file and nothing malicious.
If it is some known resource like googlePlusOne or another stable web service (or external ad), it is better to use external link. This way it will always be up to date.
If it is a library js (like jQuery or Ext) it is better to download the source.
Loading libraries from a local repository will always be faster which would suggest that local is always better, however... Loading libraries from external sources, for example jQuery, will allow your site to always load the most up to date version of the library.

Javascript file not refreshed on iPad

I have one html file and one js file.
The html file is refreshed, but the js file never gets reloaded.
I have tried clearing the history and the cache as well as turning the iPad off.
I have also deleted all nine pages in the iPad.
Finally I found a workaround. Renaming the js file solved the problem.
But it is an awkward solution.
Is there a better way?
(I'm using the oldest iPad. Can't find out any version numbers.)
To force a reload of a JavaScript file during development I typically add a query string parameter to the end of the file. Like this:
<script type="text/javascript" src="file.js?v=0.1"></script>
When development is complete for that version I include a version number in the file name.
This can be a good idea during testing even if you're not having problems with an iPad or similar. You want to be confident that people are seeing the latest version of the file and explaining how to empty their browser's cache or forcing them to refresh every page will cause problems and false bug reports.
This is a natural habit of caching. When the file actually changes, the iPad should reload the file.
This is the same as a PC browser, or any other device with caching on.
To overcome this, add a variable to the name of the javascript file, something like myfile.js?id=[ADD TIMESTAMP HERE]
On which you ofcourse add a timestamp with the programming language you use, for example in PHP: time()
I'm not 100% sure I understand your question, however if you are building a website and you don't want user's browsers to cache the javascript file I would recommend adding a build number to the JS file each time you save it and update the html reference to the file +buildnumber.js.
Example:
instead of
<script src="myAwesomeJavscriptFile.js"></script>
make it:
<script src="myAwesomeJavscriptFile.001.js"></script>
Then the next time you change it make it:
<script src="myAwesomeJavscriptFile.002.js"></script>
The other way to do it is to send down specific no-cache headers for each file using your web server (Apache, Nginx, IIS)
Good luck!

Categories

Resources