Caching problem on Azure CDN + Cloudflare structure - reactjs

Our site is being made available with the following structure:
Static Blob Container Azure > CDN > Cloudflare > User.
The React app build is made available in an Azure Static Blob Container that is accessed by an Azure CDN. When we access the app via the CDN URL, we never have a cache problem. We also use cloudflare to manage the DNS and supposedly improve the cache. But when we access the app through cloudflare, we have a serious cache problem, returning extremely old versions for users who have accessed the site before.
Even after turning off all cache options available in Cloudflare's dashboard and its graphics show that cache consumption has dropped, the bug still persists. We were unable to identify where our problem is in the structure mentioned above.

The problem is because a CDN uses multiple nodes to serve the content. The proper way to 'solve' this is appending a version in the filename or path, this way, whenever you need to change something, the CDN will download the latest version. Just using a regular 'app.js' is not enough.
More info:
How to force the browser to reload cached CSS and JavaScript files
https://stackoverflow.com/a/34604256/1384539

Related

Caching an React/Meteor webpage

I want to speed up the initial load of an React/Meteor web page.
One of several Ideas is to cache data. So fare so good...
This was tried with service workers. This was only possible for me under "/public/" folder but in addition I want to cache data from eg. "/client/" for caching more data.
Is this possible to cache more data from other folders?
I did pretty much the same as described here under "Step 1 - Add a service worker ":
https://dev.to/jankapunkt/transform-any-meteor-app-into-a-pwa-4k44
UPDATES:
we are using this Web page only in an intranet without internet connection.
things with React and Meteor don't really work that way.
It is expected to have an up to 1MB JS bundle to deliver to your client. A medium size app should look at 400-500kb of gzipped bundle size.
Don't use the public folder for assets, put everything in a CDN with edge cacheing like the AWS Cloudfront (store in S3 and expose via Cloudfront), or any other storage.
In your CDN you can set the expiry and cache-control (max-age) and this is used by the client (browser) for cacheing assets.
Deliver your JS and CSS bundles from a CDN.
Use split code extensively (ideally at routing level).
Whenever possible use async libraries form maps, players etc instead of NPM (which builds into your bundle).
With a PWA environment you will cache your bundle files not your public folder. The tutorial you followed for PWA is incomplete and useless. It only looks to how to get a green badge in the audit, it does nothing of any use.
One more thing, your Meteor bundle size impacts the traffic on your Meteor server. This is why you better deliver the bundle and all assets from CDN's.
Cacheing more with service workers only leads to flickers, inconsistencies between tabs and browsers, errors.

When using cloud foundry to deploy react apps, my users cannot see the changes unless they delete browser data

I just released my react app in a production environment in Cloud Foundry, but the only problem is that if I make changes to the app, and reupload the app, my users don't see the changes unless they clear their browser data, what can I do?
Reason for this issue: Browser is using its cache not your build to serve the client
Remedy to outcome: Inform the changes in metadata.json
metadata.json is a file that swings between request and browser checks for any mismatch with it's cache. if no then cache is served to client.
There are more then one way, thus am not telling direct solution, instead gothrough the below link will take to through various steps to follow
flexdinesh blog from dev.to

AWS CloudFront how to update existing S3 file?

I use CloudFront from AWS and I have an S3 static website.
I use ReactJs and I changed some texts on most pages.
The problem I have now is that I use
npm run build
to produce the production application. I want to update the content on AWS in the S3 bucket (I previously uploaded the same files) however two things happen:
-When I access in incognito, everything works fine, I am given the updated version of the website
-When I access in normal mode with web browsers that I used to access the website before, I am still given the old version of files.
I accessed AWS documentation and I have two solutions:
-Wait 24 hours for CloudFront to cache files in edge locations
-Use version name for the files (for example, change the name of image.jpg to image_1.jpg; image_2.jpg etc.)
I would definitely go with the second option which indeed is time consuming but for sure less than 24 hours. Should I change the name of EACH file that I have in build or just those in static?
Any other solutions?
Something I haven't tried is, before uploading to AWS S3, create a folder such as V1 and upload my react files. When I make a change I call the folder V2 and so on.
Using version names is the most robust method. It gives you full control on the cache behavior without messing around with CloudFront.
So yes, each time there's a new version update your file names.
Btw, if you bootstrapped your react app using create-react-app then the build process does that by default. It will name each bundle with a unique hash every time the bundle changes. This way you can utilize long-term cache in the browser and CF for your files.
You'd probably still have to invalidate the root index.html each deployment as its name doesn't change between versions.

CloudFront cache invalidation for React app

I have a React/redux app which is deployed on CloudFront + s3. There is no static hosting enabled on the bucket. I understand that invalidating cache on a new deployment clears cache in all the edge locations and the new changes will be served up. But what happens to the active prod users when the cache is invalidated? Are they able to continue on the app without any errors? Does it get worse for the active users if the redux store structure changed in the new version?
Clearing the cloudfront cache will bring up the fresh content from your origin. However, that would not affect the existing production users. They would continue to be served from the cached content as long as their session continues.
That being said, they would be served the fresh content when their session restarts.
There would be no errors whatsoever.
Hope this helps.
I've been wondering the same thing for my React website, which is made up of many chunks. I wouldn't worry about your Redux state unless you're saving it to cookie/localstorage and loading it again. In that case you could write some migration check during loading. Or even have it versioned in some way.
Regarding caching, I don't recommend deleting any files for up to a year. That way your active users would still be able to download chunks while they're active on your website.
During deployment I upload all the new files and clear the cache on all *.html files to get the latest reference to js and css files.

How can I leverage CDN with my AngularJS app on ASP.NET MVC?

I have an MVC project which really just serves an angular application. This will be a public application and I expect it to get a lot of traffic, so I'm trying to use a CDN to keep requests to my servers light.
I've found many articles on how to get angular itself from a CDN but what I'm looking for is for MY file (css, html, js, media) to get served from a CDN. So for example, if I have a directive, then the template would need to be served from a CDN, but I can't hard-code it because the template may not have been uploaded to the test or prod environments yet.
Update: The MVC application only serves the initial layout and home pages. Once my angular script loads MVC isn't really used anymore. The back-end is a separate Web API application.
You might be asking the wrong question, but you're on the right track for how to optimize for high traffic.
First, learn how to serve the angular application as static files. On a past project I worked on I had two projects in my visual studio solution, one was a Web API back-end, and the other was a web project that just served static content. You can configure Visual Studio to run both projects at the same time on different ports from localhost. This doesn't answer your question, but setting up dev like this will get you a step closer.
Next, once you know your project's front-end and back-end are decoupled from the server level, make sure you're not going to get an CORS issues from cross-domain requests. If you're going to be serving your back-end from a subdomain, CORS may be an issue. Look into that, you'll probably need to add some code to your MVC app to solve that problem.
Now that you've got all that figured out, find out how to use a CDN service. There are many offerings with specifics of how to deploy content and SSL certificates varying for each. Amazon Web Services, Microsoft Azure, and many others offer CDN services, but before you even look at that stuff, make sure you can actually serve your back-end from a different port on your dev machine and it still works.
I was trying to think of a good solution to this recently...
In local testing (grunt serve), i use the current non-minified .js/.css file, but when creating a build (grunt build), Id want to point those files to the CDN in my Angular project.
I'm thinking for your grunt(gulp/webpack/etc) build (which creates the minified local files for the build), you could make a task to prepend certain urls/files to your CDN via
https://github.com/callumlocke/grunt-cdnify or https://github.com/tactivos/grunt-cdn (but it would still use your non-minified files for grunt serve).
It would be cool if uploading to CDN and invalidating the files was a grunt/gulp/webpack plugin.
Then you could automate it as part of your prod builds.
Guessing your build system like Jenkins/etc would upload your app to wherever.
and then either with a grunt/gulp plugin like so could invalidate your files:
https://github.com/keycdn/grunt-keycdn if you use that CDN service.
I am guessing your build system like Jenkins could also do this work for you via its own CDN upload/invalidation plugins.
I know this answer is mentioning grunt specifically, but there should be similar plugins for gulp/webpack/etc as well.

Resources