How to deal with webpack chunk updated on server? - javascript

We have a React application with code splitting using React.lazy and Suspend. Every Tuesday we deploy a new version and so our chunks will change too.
The problem we have right now is if our user did not refresh after we deploy, their old main.js is still pointing to the old chunk files with old hashes. And it's going to crash when they try to load the old chunk files.
We know that we can prefetch routes when our app is loaded but there are a lot of routes to be prefetched (around 20). This might affect our home page performance because we have a few API calls on home page.
Are there any better ways of dealing with this?
Many thanks in advance.

What keeps you from keeping multiple versions on your server? Let's say v1.commons.js is currently deployed. Now when you build a new version, v2.commons.js gets created, and both files are served by the server. Old clients will still work with the old version, but depending on your caching settings (page expiry time) they will migrate soon to the new version. Then you can remove the old version from your server.

Use the [hash] placeholder in the your Webpack output configuration, e.g. filename: '[hash]/[name].js'. This way every compilation will yield a fresh set of filenames.
Ensure the page that refers to these chunks (be it generated with webpack-html-plugin or something else) is always served fresh, never from cache, via Cache-Control headers or other similar techniques.
This way very stubborn clients (who disregard the cache-control headers) will most probably use their old version of your code, but as soon as they refresh (to get the new HTML page), they'll be guaranteed all of the new JavaScript too, since the URL has changed.

We have decided to preload every route in background so our clients do not need to lazy load other chunks at a later point in time.

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.

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.

Updating site with git push, browser still loads old cached version

Git has made updating my site a hell of a lot easier and quicker. I love it.
However, it seems when updating files with git, my browser seems to cling to old cacheable files much longer than it should.
I have no idea if this is just my browser, if it's a quirk of git, or if it's just a problem that affects only me for some other reason.
A couple days ago I found a bug on my site, so I fixed it and pushed a new version of the affected js file to my site.
When I do this, I find if I don't hit f5, then it'll load the old js file. So I always hit f5 and think nothing of it.
But for users of my site, they are probably having the same experience... which isn't good.
So I updated the js file 2 days ago and refreshed the home page, checked it was working and left it.
Just now, I checked another page on the site, loading the exact same js file and it was still using the old cached version. I hit f5, it now loads the new one.
Is there any way I can force all browsers to forget the cached version of old files? I figured this should just happen automatically after a cache's short lifetime.
Here's the headers from chrome:
As you can see, the cache control max-age is stupidly high. My server runs with nginx+apache, and a backend system called Vesta Control Panel (VestaCP).
If I fix the cache control on the backend, how do I then tell all of my user's browsers to forget the seemingly unforgettable cached version?
This depends on your setup. If your index page is HTML, you'll want to set the server cache to expire very quickly on HTML files, so it will reload your index page frequently. (This isn't an issue with an index.php, as it should reload every time). Then you'll want to filerev your resource files.
For instance, you can use grunt, gulp, or something similar that will append a unique string at the end of the filenames for all your resources, so script.js becomes script.1a34be4sde4.js and then the next update becomes script.3ezseasd4sad.js and so on. Or you could manually rename them, adding 1 each time (script-001.js, script-002.js, etc. - although with many files this would be a pain).
This way you can keep your max-age stupidly high and the user won't have to download that version of the file again. But when your index page points them to an updated version (new filename), they'll go grab the new version and cache it stupidly long.
The problem comes with using git push to update the site. To keep your repo clean, there are a few things you could do. What I'd probably lean toward is a post-receive hook script on the server that would checkout the pushed branch to a staging folder, run a build script, and move the final version to the deployment folder.
There are a couple of cache-busting techniques that you can use, none of which are particularly linked to git (and some may be anathema to it).
In your index.html, you could use a query cachebuster:
<script src="/js/core.js?cache=12345">
Which works in some cases (most browsers, AFAIK, won't re-use cached files if the query string is different). This means you have to change your index.html every time you update stuff. There's plenty other ways to do cache busting, google around and you'll probably find a dozen at least, each of which is the "best".
Personally, I use gulp-rev in combination with gulp-inject in my build process. gulp-rev will create a hash-based uniqid for the filename (so it renames core.js to core-ad234af.js), and then gulp-inject changes index.html so it pulls that file in, instead of core.js. I only do this when doing a production build (since in dev, I have cache-control set to 0).
But this all works because I don't do git push to deploy - I use git to get the source to my production server, and then build on that server with the production flag set.

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

Categories

Resources