How do you properly handle caching static web content? - javascript

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)

Related

Is there any way to clear cache programmatically in angular 7 application?

I have a component which lazy loads the images.For the first time when my page loads then at that time the images are displayed using lazy loading but if I refresh or reload or close and then open the tab then my images are pre loaded because it is now fetched from cache.Is there any way i can stop caching of my component in angular 7?
The cache is not being done by Angular but your browser. Once you load an image (and depending on the headers of the response) your browser will cache it to be able to load it faster the next time. This is usually a good approach.
Not sure why you don't want them to be cached but you have different options. Here you have a good read about HTTP caching: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching This cache configurations for static assets are usually done by your web server and they depend on which webserver you are using (nginx, Apache, IIS, node, ...).
Another option is to append a random query string to your image URL. This HTTP cache system works by using the image URL as a resource key to identify it. Because of this reason you can do something like:
<img src="./yourimagefolder/yourimage.jpg?r=putherearandomstring">
In this way your image resource 'Id' will be different in each request. (You will need to change the 'putherearandomstring' string in the example with a different random string each time the page is loaded.
If this is just for development purposes, you can disable the cache in developer tools. I don't see a reason you would want to do this for a live site though? As you would be forcing the user to grab the images everytime they load the component which will reduce performance.
The problem with cache in an environment where custom software is updated frequently and some users are less savvy is that they will not automatically get critical client-side changes unless they are told specifically to refresh their cache. With all of the decorations in the index.html I have not yet found a reliable solution.

Magento js and css changes not reflect

I had problem that i added custom java script its included but when i changes its contents it doesn't effect. it runs older java script file. since i cleared cache. i deleted every folder of /var/ also. but still it runs older java script code. while i see it in uploaded file also it shows updated code but using URL of that java script in browser it shows old code.
I flushed magento cache storage. flushed cache of css/javascript also.
In case if any guy have solution let me know.
Thanks in advance.
EDITED
Same problem with css also. Changes doen't reflect. cleared cache a lot of times from back-end as well as cleared var folder also.
Your server probably have header information asking browsers to cache static files like JS/CSS. It is likely that your browser is still caching the old CSS files. One way to check if it is indeed the browser and not say accidentally editing the wrong CSS file is by enabling and disabling (only go one way to check) the CSS file merge. By doing so you are forcing the browser to fetch for a whole new file - essentially bypassing caching.
You may also want to take a look at our CSS/JS Versioning extension which includes automatic refresh of the file name hash based on CSS/JS file timestamps (sensitive to editing and changes) http://extensions.activo.com/css-and-javascript-versioning.html
Have you cleared your local browser cache on your workstation?
Often, CSS and JavaScript can stick mightily and no matter now much you flush Magento caching on the server, the workstation browser never requests and downloads the new script. These are static files, a change in file date doesn't trigger browser reload, only complete removal from the browser cache does.
Usually CTL-F5 about three times will do it, otherwise you have to go into the web browser setups and flush browser cache there.
Also, if you're using JavaScript/CSS Merge, you need to click the button on the Cache Management page to Flush JavaScript/CSS Cache as well.
The only other place things can gum up is if you're running APC cache, you may need to flush it as well so the block caching for the head can refresh. This only matters if you changed the script and CSS file names, which you probably haven't, so it likely doesn't matter.

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

Browser caching javascript and css files

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

Should web-browsers allow to clear(expire) cache programmatically?

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..

Categories

Resources