Subversion Repository Public Repository

litesoft

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
With a GWT App there are basically three types (or buckets) of files that are delivered to the client:

    1)  *.nocache.* (normally just the
        bootstrap JS script) - should NEVER Cache.

    2)  *.cache.* (normally the GUID encoded files)
        - should be Cached "forever".

    3)  Everything Else (e.g.: *.css, starting
        .html, images)

As the GWT documentation indicates, #1 & #2 above are NOT automatic, they suggest to configure your Web Server (Apache) to handle this.  Without this capability we either need to configure the Load Balancers or put in a "Filter" to manage the Cache Headers.

In any case the Goal is to: NOT have to tell a customer to clear their Cache (much less walk them through the process).

In my research I have determined there are basically 5 options (ignoring where we are at now, which is to NOT manage the Cache) (I have used 3 of the 5: B, C, & E):

    A) GWT encouraged way.

    B) "Ostrich" approach.

    C) Explicitly Conformant File Names.

    D) Versioning Parameter.

    E) Versioned URL.

Each approach has its Pros and Cons, I have "evolved" from 'B', thru 'C', to 'E'.  The details on each approach:


A) GWT encouraged way.

The approach GWT is pushing is to make "Everything Else" a managed resource.  This ends up putting all the contents of Bucket #3 files into the JS/HTML from Bucket #1.  This pretty much solves the problem, except for the following issues:

    - The Welcome File MUST be a regular HTML file (it should
        NOT be cached, but could be a simple forwarding file
        to a Bucket #1 file).

    - The Resulting JS/HTML files can get quite large
        (like ours) which slows down startup in an
        "no feed back to the user way"!

    - The way "Managed CSS" is injected makes the
        designer/tuner's job very painful (and it appears
        to make "CSS cascading" impossible).


B) "Ostrich" approach.

This approach is usually where you start when you JUST read the GWT documentation.  If your lucky, you learn that solving the Caching for Buckets #1 & #2 reduces the calls about messed up displays enough that you can live with it.  This is the approach we took when I was at Vantos.  The consensus was that the uses started to perceive the app as "flaky", so we started switching to Option 'C'.


C) Explicitly Conformant File Names.

With this approach the team decides for each file if it is to get ".nocache." (Bucket #1) or a ".cache." (Bucket #2) in its file name.  While this works pretty well for Images, you pretty much need to put your CSS into the No Cache Bucket, which given its size and how often it is needed sort of makes it a problem.

D) Versioning Parameter.

This approach solves the Caching problem of Bucket #3 using two mechanisms.  First, the welcome page must NOT be cached (however the welcome page could be a forwarding page to a versioned Cached URL - which starts to smell like Option 'E').  Second, all the references to all the other files in Bucket #3 get a Query String (the stuff after the '?') version appended to them.  This version changes ONLY when the referenced file changes.  For Images this is seldom.  For the CSS file it can be quite often.  Unfortunately, how the CSS file goes, so goes the containing HTML file.  This can be mitigated in two ways: dynamically generate the hosting HTML (with a templating engine, like JSP), or with the static HTML not actually having any CSS - but having the GWT code inject it (I have used the latter to support user selected "Themes").

E) Versioned URL.

This approach actually embeds a version number in the URL path (as a directory reference).  To make this tenable, rolling versions needs to be as painless as possible for all three consumers: End-Users, Developers, and Deployers.  This is accomplished in the following ways:

    - Everything is Cache "forever", EXCEPT the bootstrap
        ".nocache.js" file (which is set to No Cache).

    - The bootstrap ".nocache.js" file for old versions is
        replaced with JavaScript that preserves the URL
        token/fragment and forwards to the current version.
        This maintains a User's Bookmarks across versions
        as long as the token/fragment(s) are forward
        compatible!

    - The absolute minimum of number of files are left in
        the old version directories so that they look OK
        while they are forwarding.

    - The NON-GWT base line HTML should be kept to a minimum,
        usually just some "Loading" message.

    - Optimally the CSS should be split into two parts, the
        part to support the "Loading" minimal HTML, and the
        rest which is injected to support the GWT app.

    - All the other files from Bucket #3 are actually in an
        unversioned directory on the server, with the Versioning
        Filter remapping the URL so that they "look" to the
        Browser to be under the versioned path.

Since the Versioning Filter is already lying to the Browser (to minimize the deployment costs of multiple versions), the lying can be extended to benefit the developers.  Specifically, many of the IDE / development tools "assume" that all the resources for a Web App live in an appropriate child directory.  Unfortunately this is the very directory that GWT wants to "pollute" (from a source control perspective) with its generated files.  During development, the Versioning Filter can be told where to get the common additional resources, which is usually in a separate source controlled directory.

Finally, to make versioned directories tenable, a tool exists to automate the creation of new versions and to update the old versions to forward to the new version.

Commits for litesoft/trunk/Documents/GWTcaching.txt

Diff revisions: vs.
Revision Author Commited Message
561 GeorgeS picture GeorgeS Thu 13 Oct, 2011 22:28:36 +0000