Currently browsers have incomplete caching implementation. It only allows to set expiration or keep immediate expiration. Important 3rd option to expire cache programmatically is missing. Without that 3rd option developers cannot deploy new version of code efficiently and reliably.
If they use 2nd option it is inefficient if they have framework of many small files. Combining many small files into one is not efficient because any small change will cause whole framework to be deployed instead of one single file.
If they use 1st option updates will not get to user until cache expiration which creates compatibility problems between server side code and client side code and potentially between different parts of client side code. Setting expiration requires prediction of future deployment, which is inconvenient and will disallow quick bug fixes.
When people ask about that problem, some suggest to use version numbers or other temporary ids to trick browser cache by loading unique URLs. The problem with it is that it puts unnecessary overhead on network and local file system to load and store unnecessary old versions and tons of unique URLs. It almost defeats the purpose of caching by URL.
The right solution is to allow programmer of a web site to clean cache of files that came only from that web site. That way list of updated files could be requested and cache of newer files would be cleaned to allow browser to load fresh versions.
Proper caching mechanism is simple and powerful pattern that could boost all web client-side development to new levels, I only wonder why browser producers did not implement it yet.
Hehe, well, as far as us developers are concerned, of course!
On the other hand, cache is there to facilitate the user's experience in terms of responsiveness. It is our responsibility to work-around all these nuisances and protect the user in a shell of ignorance and all-is-wellness.
I do not think it is this easy. One problem I can see is that it is not just the browser cache. your files can be cached in many places along the way from your server to the browser (clients). Some of the browsers can still use the old version, and the answer to the question which one is cleared and what version is supposed to go to this particular client becomes really uncertain really fast.
It's an interesting idea, but how would the browser know when to ask your website if it should clear the cache? Every time the page is loaded? Wouldn't that partially defeat the purpose of caching? Set reasonable cache expiration intervals, and schedule your updates to match those, and it should be ok as it is.
I don't think what you suggest is necessary or desirable.
The client-side cache should be controlled by the user, not by you (the data/code provider). If the user wants a better way to manage his "Temporary Internet Files", then that's up to the browser developers, but I think you should not have a say in how it is managed.
For all intents and purposes, you only need to say, "this data/code is usable until X date", "this data/code is usable until Y version", or "it's never usable again".
Excellent cache control strategies can already be setup by using the existing HTTP headers (Cache-Control, ETag, etc.). If you want something to be "forced" to be refreshed, you can always add a querystring with the date on it. This is not really a hack, as you suggest, because you are saying, "get me the version of the file as of this date"... and your server has all the freedom in the world to refresh the caching policy: return "302 redirect" to the non-querystring version, or send down new headers, etc.
Edit:
I can refine my idea from above:
You can use a path or querystring to identify the "current" version:
http://somedomain.com/somepath/current/yourfile.js
The "current" URL can be setup to give a 302 redirect to a particular version of yourfile.js, while also telling the browser never to cache the current version:
302 Moved Temporarily
Location: /somepath/v3.2.3/yourfile.js
Cache-Control: no-cache;
This allows your "loader" HTML to include Javascript that decides to use a certain version:
<script type="text/javascript">
<%php
if($action == "clearCache") {
print "var version = 'current';";
} else {
print "var version = '" . $version . "';";
}
%>
</script>
they theorically do, with cache params in the header section and meta parameters
(google meta no-cache, PHP/ASP no-cache)
like cache-expires, the date that should expire etc
I agree that this is weird in most, if not all, browsers.
sometimes it works, sometimes it doesn't or takes more time to clear the cache for some reason
but would be nice to have that option in the script, like a javascript or something directly on the tags, like img src="blah.jpg" expires="my_blah_last_edited"
it could be better, true
I imagine there are great security concerns. You have anonymous and remote web-pages telling local a client to delete files on the client machine - this has all sorts of potential for disaster. Would you trust IE to do this? It just sounds too risky. There's a big difference between a directive to not cache something in the first place and a directive to delete something already in existence from the cache.
Why not embed some kind of unique tag or timestamp in the image etc. uri for each deployment, thereby causing the browser to reload?
there should be a javascript or jquery which tell the browser that content hasbeen changed and download it again even the url of content is same..
Related
Browsers cache static files. It's what they're designed to do. 99% of the time, that's a good thing. Until we as developers update that static content.
If a developer updates a javascript file, but a user's browser pulls the cached version of it, then:
Best case, it'll be missing some new functionality until the browser decides to update its cache
Worse case, if you also updated the html page to call a javascript function that didn't exist in the older version of the javascript file that the browser cached, your page breaks
As developers, we know to hit Ctrl+Shift+R, or Ctrl+F5, or open dev console, disable cache on the Network tab, and reload. But users don't know that.
What is the best practice to handle updates to static content?
Is it to make sure that when you add new functions to a .js file, you push out the update to production a few hours/days before you update the html to call that function in <script> tags, allowing browsers to updated their cache over that time?
Is it to not call javascript functions from HTML within <script> tags at all?
Is there a way to somehow force browsers to expire cache on a specific static file when you update it?
Something else?
Obviously disabling all caching on your site is possible, but not a realistic solution.
PS. I'm not using any kind of frontend framework - just raw javascript/jquery. If the situation is different with frontend frameworks, I'd love to heard about that too at a high level
If I understand correctly, you want the JavaScript file to be updated for the user when you update. you should use service work API to create a cache version for specific files or use the Google workbox library. click here. for service worker API click here
Some years ago location.reload(true) allowed bypassing the cache like CTRL / Command+Shift+R does. Only Firefox continues to support this feature by now, but the hard reload using javascript is no longer supported on chromium based browsers. (spec doesn't describe this feature (anymore))
This change was also discussed on this issue on github/Microsoft/TypeScript and several other places on the web.
jQuery uses a simple workaround to be compatible with almost everything. If you load something with jQuerys jQuery.ajax({ url, cache: false }), it appends a _=TIMESTAMP parameter to the url, which has a similar effect but may bloat the cache.
You can make use of the Entity tag header (ETag). Entity tags are similar to fingerprints and if the resource at a given URL changes, a new Etag value must be generated by the server, which is a similar behavior to the Last-Modified header. (caniuse:etag)
Entity tags in: Apache, IIS, nginx (nginx docs), nodejs
It is also possible to clear the sites cache with a Clear-Site-Data: "cache" header. (mdn, caniuse:clear-site-data)
I'm currently on a Bluehost shared hosting service, and for whatever reason my javascript files, upon change in the server's directories, will still be served as their old version until 10+ minutes passes. This is making development extremely slow and difficult. Is there any reason the server is doing this, and is there a way to disable whatever sort of caching is going on?
First, check that it isn't your browser caching - in Chrome developer tools, you can disable caching. Perhaps also try a private window. If that still fails, the hosting service may have caching (would make sense for their business).
Cheap hack though - add a timestamp value as a query parameter for all script tags, eg:
<script type="text/javascript" src="script.js?t=12345" /><script>
how you accomplish this is up to what sever-side code you're using. The changed URL should defeat caching and won't affect the script.
I am working on a site for an intranet. I want to optimize for performance, and I know the script I am loading won't have frequent changes to it. Is it better to cache the string of it (from an xhttp request) into local storage along with an expiry time like an hour or so. And then load from local storage and insert dynamically into the DOM.
Does anyone know if this method is still a good one to use? The browser I need to use is IE11 (IE10 rendering mode). Or chrome 49.
Thanks
Forget "still," as described this was never a good idea. The web browser can handle all of the caching for you, just set appropriate cache headers (in your case, to not bother to check back — not even an If-Modified-Since request — for an hour, as that's what you describe doing with local storage) and let the browser do its job.
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
I understand that the browser is forced to fetch a new version of the cached JS file when the file name is changed or a query string is added to it.
We don't do this and until now we've never had issues with browser serving stale files. Recently, we are seeing some users using IE9 who complain about the browser serving cached JS/CSS files. This issue is not consistent across everyone using the site.
My understanding is that when the file name or query string is not changed, but the JS file content is changed, the browser would fetch the new version.
Why is this happening and why is it not consistent?
Any thoughts?
Setting an expiry date or a maximum age in the HTTP headers for static resources instructs the browser to load previously downloaded resources from local disk rather than over the network.
This is good if we want to actual cache the resource. If we want to force a new download set no-cache, which forces caches to submit the request to the origin server for validation before releasing a cached copy, every time. This is useful to assure that authentication is respected (in combination with public), or to maintain rigid freshness, without sacrificing all of the benefits of caching.
HTTP Server-Specified Expiration - specs
Yes, when the content seems the same (i.e. same file names), users may get a cached version of those files on subsequent visits.
It is really beyond your control... it's up to each specific browser to decide how to handle caching and it's also up to the user... some dump their cache regularly or refresh the page if something doesn't seem right.
If you want to force the user to see your updated CSS or JS content, change the CSS or JS file name... otherwise it may be inconsistent for a short, but unknown, period of time.
This tutorial may help you...
http://www.mnot.net/cache_docs/
For example Chrome caches scripts until Shift + F5 or some time expired ( and ignore the fact it is changed on server, it don't even send a request ).
So is done by other browsers ( but when cache is enabled ) - i cannot descripe exactly when it happens