3

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.

aez
  • 2,406
  • 2
  • 26
  • 46
  • The difference to HTML5 storage is, that the cache used for client bundle resources etc. is purely the standard browser cache for HTTP resources, which caches automatically based on the URL and HTTP caching headers, whereas you would manage what gets into HTML5 storage yourself with your app. – Chris Lercher Sep 29 '12 at 18:22

3 Answers3

5
  • 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.

Community
  • 1
  • 1
Chris Lercher
  • 37,264
  • 20
  • 99
  • 131
4

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.

Andrei Volgin
  • 40,755
  • 6
  • 49
  • 58
  • Thanks Andrei. Can you please explain what "external text resources can be cached like all other static files" means? I'm hoping to achieve a situation where a large file is only downloaded once, then somehow magically stored in the "cache" whatever that is, so that with future calls to the app, the file won't need to be downloaded again. Does ClientBundle give me that? – aez Sep 29 '12 at 17:42
  • There are different types of ClientBundles. ExternalTextResource does what you need. Allowing static files to be cached by browsers depends on which server you use. For Apache you enable mod_expires. For Appengine, you modify appengine-xml. Etc. – Andrei Volgin Sep 29 '12 at 18:15
3

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.

Daniel Kurka
  • 7,973
  • 2
  • 24
  • 43
  • Thanks Daniel. So if I have a large 100MB file in my client bundle, then it will have to be downloaded (as part of the compiled javascript) each time a user starts the app? I thought the point of the ClientBundle was to make use of the cache? – aez Sep 29 '12 at 12:58
  • clientbundle is not about cache, its about having the resources directly in your javascript (which will be cached), but a 100 MB resource is not suitable for clientbundle (and not for a download as well...) split it up with service calls! – Daniel Kurka Sep 29 '12 at 13:39
  • The Google site says "The resources in a deployed GWT application can be roughly categorized into resources to never cache (.nocache.js), to cache forever (.cache.html), and everything else (myapp.css). The ClientBundle interface moves entries from the everything-else category into the cache-forever category." So it sounds to me like ClientBundle does indeed use the "cache" whatever that is exactly. Does this change your mind Daniel? – aez Sep 29 '12 at 17:44
  • thats exactly what I said in my last comment – Daniel Kurka Sep 29 '12 at 18:21