Javascript and css caching in asp.net - javascript

I know this question was asked quite a few times and the most common answers were:
Auto versioning using the .htaaccess file.
Although this is not at all recommended, using a version number as a query parameter
For example: '/scripts/script1?v=1.0.0'. This will cause the browser not to cache the file but does the job.
I am handling some post release issues and since we don't follow a software project life cycle as such, we update the site as and when the issues are tested and fixed. So, we may have to update the site several times a day sometimes versus no updates for a week.
I am not sure if there is a way I can still take the benefit of caching and at the same time don't need to have the users to refresh the page/clear cache to see latest changes.
Is there a way I can implement the .htaaccess solution in asp.net if that's what I need to do?
I really appreciate any help.

Here is the solution I've used for css files, but should work fine for JS:
In the htaccess have a rule:
RewriteRule ^(.*)_ver_.*(\..*)$ $1$2 [NC,L]
That takes a file name such as "Style_ver_12345.css" and rewrites it to Style.css.
Then when when you include the file append the LastWriteTime of the actual file (File.GetLastWriteTime(filePath).Ticks.ToString() is how I do it) as the version number. An example file name that I would have is Style_ver_634909902200823172.css
This will ensure that any change in the file will immediately cause a new version number, while the physical files does not need to have a different name, and the file will be cached by the browser.
The user would still have to refresh the page, but they wouldn't have to clear their cache. If you needed to, maybe you could force a refresh by having an ajax call that would compare the version number of the script loaded with the version number on the server. A newer version on the server could then force a refresh.

Related

Angular2 force/hard reload of browser cached scripts?

I know that there are a lot of posts about that in web, but none of them satisfied me.
Most of people recommends appending a verizon number to each script/css file. But this sound like a lot of job to me (project is qute bit), maybe there is some way to version only output files, some CLI command I dont know?
My solution was based of simple pinging to API for new version number, when > than stored then reload the page. And here is a tricky part - even location.reload(true) does not refresh the cached angular stuff. Manually CTRL+SHIFT+R does this job nicely. This would be good enough for me if the programmaticly hard reload would work.
I also tried a this.compiler.clearCache(); but also with no effect.
Thanks in advance! :)
The #angular/cli does the cache busting for you. It appends the hash to script/css file names if you run the ng build with the --prod flag.
EDIT: If you are using the angular-cli, the #Tomasz's answer is probably better than the methods listed below.
Ideally you would use a module bundler like Webpack or a task runner like Grunt to automatically 'fingerprint' your files (ie, append a unique identifier to the file name based on it's contents).
But if that is not an option, a simple hack would be to :
set the caching headers on your HTML to avoid caching on the browser
Append a random query parameter to your script tag URLs in your HTML which you can change each time you want a new version.
<script src='/js/some.js?v=1.1.3'></script>
Changing the random query parameter (v in the example) will ensure the browser makes a fresh request as the URL is different than the cached (older) version

Force reload after new version in DOJO

I am providing an infrastructure that require the developer to include only one simple java script file that then includes allot others, for instance DOJO toolkit. Later DOJO is loading all\some of my infrastructure files.
When i'm updating the version i'm simply telling my clients to include the version number in the <script src="...?ver=1.2"> so it will not take the files from the cache.
My problem is that (this simple file is being reloaded but) the rest of my files that being loaded by DOJO are still being loaded from the cache.
Is there a way to do the same technick, or maybe other way, to force my browser take the files from the server at this time, and not from the cache ?
As usual, I am posting question and answering myself. But sharing the answer so it will use others and not deleting the post.
Using dojoConfig property cacheBust is the solution.
dojoConfig = {
...
cacheBust="v=1.2.3",
...
}
In DOJO documentation it's stated that when you send true it will add the time as query string. Which means that every load will be from the server and never from the cache. but what we can do is adding constant string as i wrote above v=1.2.3 and this string will be added as the query string as well, and giving us more power on when the version will be loaded from cache or server

Modernizr.load and performance (cache) for conditionally loaded async resources

I read about a dozen posts on here, this one seemed closest but didn't quite clear it up for me.
I am building on HTML5 Boilerplate, albeit a custom Modernizr build. I am planning on using the yepnope/modernizr.load functionality for conditional loading.
The .htaccess in H5BP removes Etags and adds expires headers (I guess expires headers are required for Modernizr.load). It also set expirations of "access plus X"
How does this work in relation making the most of cache to 'speed up' the browsing experience. Will every resource who's conditions are met load on every page or will things which are cached be skipped?
What if just one of the components (one of the resources I am loading) is changed yet my version of Modernizr isn't?
After posting I realized this may more suited for the webmasters forum (there's no actual code in the question...) but I guess I am unsure if there will be an answer that involves code so for now, I'll leave it realizing perhaps it should be migrated. Sorry, this level of coding and configuration is new to me.
Thanks
Each resources is cached independently. So, if you load a javascript file named foo.js, this file will be cached for one year: https://github.com/h5bp/html5-boilerplate/blob/master/.htaccess#L245
If you change your modernizr script to a new version, this won't change the cache end date of foo.js which will remain untouched.
In order to bust the cache, you'll need to change the file name (e.g.: foo-v1234123.js), the path or you could add a query string (foo.js?v=1). If you make change to foo.js then just increase this version number by one to force the browser to redownload the file and recache it.
If you're working on a simple website and no big project, using a query string a doing this manually may be the easier solution. Or else, I'd suggest to hooks versions number via git or something similar - but this would need to be automated for your sanity.
Hope this help !

jQuery file name

This one should be easy, and I think I know the right answer, but here goes.
For compatibility reasons, should I leave the filename of jQuery as "jquery-1.3.2.min.js" or just rename it to jquery.js?
My guess is leave it as is to avoid conflicts in case another app uses a different version of jQuery. If they've renamed it to "jquery.js" and I do the same, I see potential version conflicts.
Am I wrong or way off base?
Jeff
It's a very good idea to have version-numbered JS (and CSS) files, because that lets you configure your web server to use a far-future Expires header on such files without running into caching problems. When the file gets updated, it gets a new version number, so the browser always fetches the new version, not the old cached one.
You should do this on your other JS and CSS files, too. You want this to be automated, not something you manage by hand. Your development work happens on unversioned files, and your versioning system creates versioned copies and works out the details of updating the references to the CSS and JS files in the HTML files to point to the versioned copies. This can be a bit of work, but well worth it when it comes to speeding up your site. It took me about a day to set my system up. The improvement wasn't subtle.
I would go with jquery-1.3.2.min.js because it's more specific and you can immediately tell if you're reviewing this site in months to come, as well as avoiding any filename confliction in the future.
You shouldn't have any issues with updating, if you're relying on something like an include/template file for the javascript.
In my opinion, its just a personal preference. If you have version in your file name, It helps you easily identify which one you are using with out actually opening the file. It also provides an indirect way of clients downloading the new version file (as it is never cached). If you don't use the ext, upgrading to newer version is easy in coding perspective, but takes the pain of force downloading the new file by all users.
Recommended way to use jQuery in app is using the google's hosting..
google.load("jquery", "1.3.2");
google.setOnLoadCallback(function() {
// Place init code here instead of $(document).ready()
});
Why and how to use jQuery hosted on google
I prefer to leave the version in the file name because there are times when you are changing versions and this is very helpful. At a glance I can see which version I am using on any given webpage.

How to deal with browser cache?

What are your tricks on getting the caching part of web application just right?
Make the expiry date too long and we'll have a lot of stale caches, too short and we risk the servers overloaded with unnecessary requests.
How to make sure that all changes will refresh all cache?
How to embed SVN revision into code/url?
Does having multiple version side-by-side really help to address version mismatch problem?
Look at the minify project. It's written in PHP but you could use it as a blueprint for any language.
Key features:
a config file to combine & minify several js or css files into one
always uses the last modified date of the last modified file in a config group as a URL parameter
example resource might look like
<script type="text/javascript" src="/min/g=js1&1248185458"></script>
which would fetch the 'js1' group of javascript files in your configuration with the version number "1248185458" which is really just the last modified date converted to epoch time.
When you put updated js files on your production servers, they'll have a new modified date which automatically becomes a new version number - no stale caches, no manual versioning.
It's a very cool project with some really well thought out ideas about optimization and caching. I've modified the process slightly to insert YUI compressor into the build process. You can optimize it even more by preventing the last modified lookups from the browser by modifying your server's headers (here and here).
I think you are on the right track with putting version numbers on your js css files. And you may want to use a build tool to put all of this together for you like http://ant.apache.org/ or http://nant.sourceforge.net/
Couple of ways to deal with this issue:
Following the clue given about using version #s, if that presents difficulties for you in your build environment it is also just as effective to put a URL parameter at the end of your URL. The browser clients will treat each URL with a different version parameter as URL no in their cache and will download the file again. The servers won't care that the parameter is there, for static content
So, for example, http://mydomain.com/js/main.js can be included in your HTML as http://mydomain.com/js/main.js?v1.5. It might be easier for you to pass version #s into your serverside scripts and append them onto your clientside include URLs.
The second method I've seen work well is to use a controller serverside to deliver your code. Facebook makes use of this. You will see includes in script tags that end in ".php" all the time.
E.g.
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
Their backend determines what JS needs to be sent to the client based on the environment that was sent up in the request.

Categories

Resources