Introduction
Context
The Application Cache feature describes a cache manifest resource which describes all resources which are accessed by the web application. Some of these resources are static, and others are dynamic (meaning, a network RPC-kind of resource).
The browser (at least, iPhone Safari) loads the cache-manifest and immediately obtains all resources in the manifest. The manifest is from this point regarded as a proxy to the actual internet (not just the originating web server), so if the app tries to load a resource not listed in the manifest, it is rewarded a 404 NOT_FOUND and the resource is not loaded.
Problems
Here we found several problems we can't solve with the current status quo:
- The cache-manifest must be set in the <html> tag of the index.html page in order to be effective. This means the manifest must list all permutation resources generated by GWT, obviously resulting in a large network overhead in initial loading time;
- If the cache-manifest must be permutation-specific (to narrow down the pointless network overhead) the browser should get to a page representing a particular permutation;
- If the user is redirected to a different page, the user should be able to bookmark the page for later reference (and effective offline access);
- Not just the cacheable resources, all other resources must be listed in the manifest. This means the AppCache library must be provided some means to detect a new version of the webapp, so it can update its cache.
Proposed solution
The IFrameLinker (which is the default linker in GWT) seems to be the best extension point for this effort. We need to:
- add a manifest attribute to the <html> tag of the landing page pointing to the general cache-manifest. This manifest lists all resources referred to from the landing page (like CSS) and the permutation-specific HTML resources (5646ABCDEF565.cache.html) as CACHE entries;
- Split the permutation-specific HTML generated by the IFrameTemplate in two parts: One is the basic HTML document (which is just a wrapper for the <script> tag), and the other is the included permutation-specific Javascript;
- The permutation-specific HTML gets its own manifest attribute pointing to a permutation-specific cache-manifest resource. That cache-manifest lists just the included permutation Javascript as CACHE entry.
- Collect the NetworkArtifact instances generated by the ApplicationCacheNetworkSectionGenerator and translate them to entries in the NETWORK section of all permutation-specific cache-manifests resources;
- Collect the static resources emitted from GWT and store these as entries in the appropriate cache-manifest resources.
The output from the linker should work on all GWT supported browsers, including browsers which don't provide support for the Application Cache feature. In that case, the cache is simply ignored and all resources are requested normally.
Also, the output should work perfectly well in Hosted Mode too.
Will you upload an example of this behaviour? Thanks a lot.
Can't this be acchieved with a Gwt linker?
the solution seem quite complex, why don't you simply generate a static cache.manifest with all the resources file to be cached?
@cristiano.costantini: Everything that's specified in the cache.manifest has to be downloaded, or the cache won't work. The issue here is that GWT creates many versions ("permutations") of a single webpage, one for each major brower. So including all ressources would result in huge traffic overhead, as you get to download e.g. all six versions of a webpage, when you aonly need one copy (yours).
@bguijt: I believe problem 4 could be solved with an asterisk (*) line added to the Network Whitelist. This will cause the browser to actually contact the server for any unspecified resources. (http://www.w3.org/TR/html5/offline.html#concept-appcache-onlinewhitelist-wildcard). Or am I missing something?
@felix.alcala: Yup, problem #4 is solved using an asterisk in the manifest.
All mentioned problems exist because of GWT's nature of creating multiple Permutations per browser/locale/whatever. Since GWT 2.0, however, we have the Soft Permutation feature which eliminates all problems mentioned above (provided the application is compiled, in the end, to a single Permutation).
what is the status of the development? I could help.
Hi Felix, I come back after many thoughts on the subject and after almost finishing a wonderful book, that considering your project, I really would recommend to you: "Programming the Mobile Web" by Maximiliano Firtman, published by OReilly. The topic of Offline webapp is taken into consideration into the book, along with many other considerations about performances, caching, etc.
It is true that GWT generates many permutations "for each major browser" but the project targets "mobile" browsers (gwt-mobile-webkit) and there are some considerations to be taken into account:
Tu summarize it up, I think that the first version of AppCacheDesign should generate a static cache magnifest with all the files generated by GWT compiler, and leave to developers the responsibility to build up only permutations for the platform they target, and to compile a different applications (the same project could include many gwt.xml modules) for different platforms.
In the end, I want to say thank you for your effort on the project! (I really would love to have the time to help you)
Cristiano
@javimena: There are some sources checked in SVN which are there to try the proposed solution outlined above on this page. These sources compile to pre-GWT 2 only, due to changes in GWT2 concerning the runAsync capability. The existing code would mostly be removed, it doesn't work.
You're welcome to help! Please share your ideas and/or code if you like.
@cristiano: Thanks for the thumbs up! As for your considerations: I need to rewrite some of this page to improve the problem description, and add new (GWT2) potential solution directions which make this feature all the more accessible.
Re the user agent support: The most difficult mobile browsers are featured in Blackberry devices (old WebKit?) and Symbian S40 devices (also old WebKit?). I am not sure whether GWT is suitable for these browsers, since they barely run Javascript at all.
did you look at this approach? http://webcentersuite.blogspot.com/2011/05/writing-gwt-linker-for-offline.html