GWT Caching Concept - gwt

Can someone explain to me in simple term the concept of caching in GWT. I have read this in many places but may be due to my limited knowledge, i'm not being able to understand it.
Such as nocache.js, cache.js
or other things such as making the client cache files forever or how to make files cached by the client and then if file get changed on the server only then the client download these files again

Generally, there are 3 type of files -
Cache Forever
Cache for some time
Never Cache
Some files can never be cached, and will always fall in the "never cache" bucket. But the biggest performance wins comes from systematically converting files in the second bucket to files that can be cached forever. GWT makes it easy to do this in various ways.
The <md5>.cache.js files are safe to cache forever. If they ever change, GWT will rename the file, and so the browser will be forced to download it again.
The .nocache.js file should never be cached. This file is modified even if you change a single line of code and recompile. The nocache.js contains the links of the <md5>.cache.js, and therefore it is important that the browser always has the latest version of this file.
The third bucket contains images, css and any other static resources that are part of your application. CSS files are always changing, so you cannot tell the browser 'cache forever'. But if you use ClientBundle / CssResource, GWT will manage the file for you. Every time you change the CSS, GWT will rename the file, and therefore the browser will be forced to download it again. This lets you set strong cache headers to get the best performance.
In summary -
For anything that matches .cache., set a far-in-the-future expires header, effectively telling the browser to cache it forever.
For anything that matches .nocache., set cache headers that force the browser to re-validate the resource with the server.
For everything else, you should set a short expires header depending on how often you change resources.
Try to use ClientBundle / CssResource; this automatically renames your resources to *.cache bucket

This blog post has a good overview of the GWT bootstrapping process (and many other parts of the GWT system, incidentally), which has a lot to do with what gets cached and why.
Basically, the generated nocache.js file is a relatively small bit of JS whose sole purpose is to decide which generated permutation should be downloded.
Each individual permutation consists of the implementation of your app specific to the browser, language, etc., of the user. This is a lot more code than the simple bootstrapping code, and thus needs to be cached for your app to respond quickly. These are the cache.html files that get generated by the GWT compiler.
When you recompile and deploy your app, your users will download the nocache.js file as normal, but this will tell their browsers to download a new cache.html file with the app's new features. This will now be cached as well for the next time they load your app.

Related

Never revalidate cached assets PWA service worker WorkBox

So I'm having an issue and I think I know what's happening but I'm not sure.
I have a PWA being deployed in versions. Each version obviously some files change. My bundler hashes the files into files (eg, /assets/OnboardingIntro.89e181b7.css).
What was happening was that when there would be a new deployment pushed along with a new manifest/SW, sometimes, there would just be a blank screen. A refresh fixes the issue.
In the network tab, it would say something like 'text/html' is not a valid JavaScript MIME type.
I figured this was happening because new PWA assets would be pushed with different hashes (for good reason), and the old ones would be deleted (also desirable). And what was happening was that on this current load, the old SW was requesting revalidation of its files. Even the SW worker was being told to cache these files, perhaps there was some logic that was re-checking them. And because rewrites go to index.html, these JS files were then being recognised as HTML causing errors.
Upon further inspection I found this header in the JS file:
cache-control: public, max-age=0, must-revalidate
Which suggests that the reason this is happening could be because the browser is being told to revalidate the SW's cached files every time.
But I would like really understand the logic behind re-validating cached assets in service workers. Can I guarantee that an installed service worker would never update a cached file until a new SW/manifest has been initiated? Because that's the only I can see this issue being solved. Otherwise every time I make a new deployment there's a window in which an old service worker might ask for an old file that no longer exists.
What is the logic behind revalidating? Does the SW use the cache headers? Is it just a matter of setting the cache header to an insanely long time? Is there another setting in the service worker, or in WorkBox to do this?
Another question would be, if an old asset and new asset's filenames matched, and these cache headers were set to infinity, would the new SW force a single revalidation to grab the new file? Or would it fallback to the old one if it's cached in the browser?
Thanks!

Meteor 1.4 - General approach to file system + /public activity

I've done some digging around and a lot of the threads regarding file system and how it works with Meteor seem to be pretty outdated, not to mention packages related to file storage/serving (i.e. CollectionFS). I was wondering if anyone here has deep experience with handling files in lieu of 1.4 or even 1.3 (I am currently on 1.4.1.1).
My questions are as follows:
Did Meteor 1.3/1.4 come with any changes regarding fs?
What is the general best approach to storing and serving static assets in light of Meteor 1.4?
I've seen many threads that say dynamically storing files to /public triggers a server upload, but I've tested this on local by manually copy/pasting a .png file into /public, and it only triggers a client refresh with the console message Client modified -- refreshing. Would this hold true for files added during runtime, and would it hold true in production?
Currently I am trying to stay clear from S3 or any other third party CDN's to keep a low budget, and also trying to stay clear from storing files into Mongo.
Thanks for any and all opinions!
What about setting up a shared folder or NFS folder, have your Meteor app handle the file upload, write the file to that location, and configure Nginx or whatever you are using as the load balancer to serve those files. If you worry about browser refreshed when the file is put into the public folder, you do not need to write files to the public folder right?

Maintaining (version + redirect) in S3

So, far in our application, the *.js files were served directly from apache. For example, this was a script include in a jsp page : /foo/v6565/my_script.js. The v6565 in the path is phony and an internal apache redirect, redirects /foo/v6565/my_script.js to /foo/my_script.js.
Whenever my_script.js is updated, v<xxxx> in the included jsp page (an internal tool does it based on the SVN revision of my_script) is updated - thus forcing the browser to fetch my_script.js again and not the cached version. I hope I am able to explain my current approach clearly.
[A different approach could have been to user /foo/my_script.js?v=5652. However, there was some caching issue (can't remember it) because of which the decision was taken to use /foo/v56564/ instead of adding version to the queryParam. I will dig into it, though]
Now, that we are moving all of our *.js files to an s3 bucket, I was wondering what would be a way of doing this?
The path from s3 bucket would look like : mybucket.aws.com/js/my_script.js. How to I insert the version tag + redirection for s3? Are there any other standard approaches used when resources are served from s3?
(I've read about page redirects on s3 resources but the redirects are to be written directly on the resources, which is not really applicable in my case)
Thanks.
I think cache busting with ?v=<hash> is pretty much standard now.
It has been disadvised, however that's a pretty old resource (though often cited) and I'm not sure if this is still true. Even your trusted StackOverflow is using it with SHA1, so I guess it's good enough for everybody now.

How I can clear JRE cache dynamicly in java applet

Here is code:
<applet code="ATest.class" archive="ATest.class?v=200406181300">
</applet>
I want to clear existing cache and load the new one when it loads 1st time.How can i do in java applet?
I tested it in Firefox 0.9 and it loaded and ran the class. The idea here
is that when you change the class, you change the [v]ersion in the ARCHIVE
attribute. That should force the browser to get a new copy of the class
file, since the "archive" is now at a different URI, and since the
"archive" is the .class file, it might work (unless the user agent
disregards ARCHIVEs that are classes, which is entirely possible)
I don't think the applet can so this.
But I don't think it needs to either. If the changing the v parameter to a different value isn't sufficient to get the browser to request a new copy of the class, then put it into a JAR file and arrange that the JAR file's name changes each time you want to deploy a fresh version.
I should note that forcing the browser to download a fresh copy of a class if it hasn't changed is a bad idea. It won't achieve anything useful. On the contrary, it will waste server and network resources, and it will make the page load slower.
First, read your question: Why would one update an Applet, "when it loads 1st time"? If you mean the second time, when the plugin tries to load it from its own cache, than just use a new codebase, maybe a new one for every visit/or.

How does GWT ClientBundle caching work?

I am trying to better understand the use of GWT ClientBundle and caching.
If I have a large text file, for example, that I'd like to make available to my client, I can use
public interface MyResources extends ClientBundle {
public static final MyResources INSTANCE = GWT.create(MyResources.class);
#Source("myText.txt")
public TextResource myText();
}
//-- then later to use the text
String text = MyResources.INSTANCE.myText().getText();
Does this mean that the file "myText.txt" would be downloaded from the server the first time the client runs the app, and then the file would be stored in the browser's cache so that in future uses of the app, the file does not need to be downloaded?
If so, what happens if I change "myText.txt", does the app know to get the new version?
Finally, if the file is indeed stored in the cache, how then is this different from local storage in HTML5?
Thanks.
As Daniel Kurka already mentioned, the resources can be inlined in the js file (a *.cache.* file) where the rest of the compiled GWT code lives.
Inlining does not occur for all resources in a client bundle. E.g. large images are never inlined, it can also be prevented with #ImageOptions.preventInlining(), and it doesn't occur for ExternalTextResources.
What's common for both cases is, that the results will be in *.cache.* files, with unique names that change automatically whenever the contents of a source file change (you'll have to recompile the GWT app though!)
This allows the server to deliver these files with appropriate caching HTTP headers (you'll have to set this up yourself!) For the client this means, that it will not only be able to cache the contents (which it does anyway, even if those headers aren't set), but it can even skip asking the server, if a newer version exists.
The big advantage of ClientBundles is, that the file names will change automatically. The biggest disadvantage is, that you must recompile your GWT app, when a resource changes. If you don't want that, then it's better to use some other approach to load the files: You can still make the browser cache any file you like (by setting the HTTP headers), but then you'll have to be careful to manually give them a new name, when the content changes.
You should use an External Text Resource if you want it to be loaded on demand and not as a part of compiled JavaScript.
https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#TextResource
If your users need the entire file, use one text resource. If users need parts of it, split this file into separate smaller files: only the requested file will be loaded when needed.
The external text resources can be cached like all other static files.
Files that are inside a clientbundle get inlined into your compiled javascript. They will not be downloaded separately. If you want to download a resource at a given time you can easily use request builder for that.
If you don`t want to download the file immediately but you still want to inline it, you can use code splitting and put the bundle into another part of your app.