How does GWT ClientBundle caching work? - gwt

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.

Related

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.

GWT Properties file configuration

I am new to GWT, and facing one problem.
How we have .properties file for initial configuration at startup.
I want to create one in GWT App.
Also, GWT has client and server package.
I want to setup the configuration at client package because all configuration belongs to client side.
My actual need,
I have one textArea which takes up only fixed number of characters and length is defined in my properties file like below.
So I have to read a properties file for validation.
my.properties
smsConstraintEnabled=true
smsConstraintCharLimit=160
I found few link but all are talking about properties file regarding Locale, I don't have any need on Locale side but need simple key-value configuration.
I want this file to be loaded at startup or at Entry point itself and then I can use it at any client package classes for my validation.
Thanks in advance.
Use a Constants interface. It's built with I18N in mind but will work just as well in this case, where you provide the constant values for a single locale, the default one (therefore used for every locale you'll compile your app with).
That however means the file is read at compile-time, not runtime (i.e. you'll have to recompile your app each time you change the properties file).
If you want something more dynamic, then read the file on the server-side and pass the information to the client-side. Easiest, and with minimal overhead, is to use a dynamic host page. To read the values in your client code, then either use a Dictionary (and Integer.parseInt et al.) or use JSNI (possibly with an overlay type).

Deploy GWT Application as Single JavaScript File

The compiled JavaScript output of a GWT application is divided into various files, for instance
*.cache.html
*.gwt.rpc
hosted.html
*.nocache.js
...
I know this is done with the purpose of minimizing the size of the JavaScript, which has to be downloaded by users. For instance so that a Firefox user does not have to load the JavaScript specifically compiled for IE6.
However, especially for small GWT applications it might often be faster to download a single file of say 500kb rather than make two sequential requests first for the 5kb *.nocache.js script and then for the rest of the app (cache.html files, etc.).
This leads me to the question: Is there any framework or procedure to bundle the output of the GWT compiler into a single JavaScript file?
First, you can merge all permutations in a single file by using so-called "soft permutations".
Then, you can inline your *.nocache.js into the HTML host page (e.g. using a JSP's #include directive) to cut one additional request (you might have to add a <meta name=gwt:property content='baseUrl=myapp'> where myapp is the subfolder where the .nocache. files are located).
AFAIK that's what Google are doing for their GWT apps.
Alternatively, you can run the permutation selection on the server-side if you can totally replace the selection script (*.nocache.js) with server-side content negotiation (based on User-Agent and Accept-Language request headers for instance) that can directly generates a <script> tag for the appropriate *.cache.js file (provided you use the xsiframe linker).
AFAIK, Google use all these techniques for their GWT apps (such as Google Groups). For a small app, though, I'm not sure it's worth the effort…
Also, the last two techniques work best when your HTML host page is already dynamic and therefore already non-cacheable; otherwise you're mostly moving the problem, not solving it.
I wonder whether the sso linker can be used when you collapse all properties and soft-permutations down to a single hard permutation.
Yes, but it's maybe not something you want. See this answer: https://stackoverflow.com/a/4453716/66416 to this stackoverflow question: Merge GWT generated files.
I found another way to accomplish this: Writing a custom Linker for GWT. Two examples for linkers which compile into a single JavaScript file are:
GwtNodeLinker.java from Gwt Node project
ServerSingleScriptLinker.java from Env.js project

Single image with GWT 2.4 requires an ImageResource?

I was just adding a single image to a GWT 2.4 application I was working on. I just put it under the images folder in the war and I had it working properly until I would compile it. Then it would get deleted from the folder. If I remember correctly, from working with older versions of GWT, you could just put an image in this folder to use it.
It just took a few minutes to convert the code to use an ImageResource, but do you have to use an ImageResource for just one image or is there another way to do this?
The class ImageBundle is deprecated, try to use ClientBundle instead.
Instead of putting the file in the war folder, which is typically generated, try putting it in a folder called public/ in the same directory as your client package. The compiler will move it then into your module directory.
And finally, ClientBundle (and ImageBundle, but don't use it) will automatically try to sprite your images where possible, and in some cases include the image in your main html download so that the user only needs to download and cache one large file instead of several files - even for individual images it can be worth it for repeat users of the page, to ensure that no caching issues ever occur.

GWT Caching Concept

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.