I thought I have been successfully cache busting with angular-cli's --output-hashing
option set to all
to ensure users get the latest chunks/updates. I realized this isn't always working for lazily-loaded modules.
If I make changes only to a lazily-loaded module + build + deploy to IIS, AND go to a URL that belongs to the lazily-loaded module, then I get the latest changes as expected.
However, if I close and re-open the browser and go to a URL that does not belong to the lazily-loaded module, and then click to a link that takes me to the lazily-loaded module, the latest changes are not observed.
It's almost as if browser is assuming nothing is changed whenever I enter the app from a module that hasn't changed, and doesn't pick up the new chunk later when I visit the module that is changed.
Even stranger, when I tried to replicate the issue to provide some screenshots, the issue went away.
Has anyone else experienced inconsistency with cache busting using output-hashing?
Edit:
After investigating some more, it turns out that if I go to the landing page of my site [IP address]:[port], then the index.html comes from the cache.
Instead, if I go to any other route [IP address]:[port]/[route], then the index.html comes from the server.
Since index.html points to inline.(hash).bundle.js, which in return points to lazily-loaded modules, getting the old copy of index.html results in getting old versions of inline.js and other modules.
I tried to add <meta http-equiv="expires" content="0" />
to index.html and cleared browser cache, and still got the file from cache.
I also tried adding a section into web.config, but this did not work either.
How to ensure index.html always comes from the server?
Your answer can be found in this SO related question, which outlines how to set up IIS to set the cache settings for the index.html
file: How to disable caching of single page application HTML file served through IIS?
Additionally based on the Mozilla Docs, you should set the Cache-Control
header to this: no-cache, no-store, must-revalidate
As for the cause of this issue, when Angular is generating the output bundle, it will create JS filenames that will uniquely identify the current version of that file if told to use output hashing (i.e. they create a hash of the file contents and include this in the filename so that browsers do not serve up the cached version of these updated files: js-filename.[hash of content].js
instead of just js-filename.js
). The problem with this is that the browsers will also serve up the cached version of the index.html
file that Angular generates, which will point to the old version of the JS files.
To resolve this issue, you must set up your web server to set the appropriate Cache-Control
setting (outlined above) on the index.html
file so that the browser never caches this file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With