GWT ClientBundle缓存是如何工作的?

3

我希望能更好地理解GWT ClientBundle和缓存的使用。

例如,如果我有一个大的文本文件想要提供给客户端使用,我可以使用:

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(); 

这是否意味着当客户端第一次运行应用程序时,文件“myText.txt”将从服务器下载,并且该文件将被存储在浏览器的缓存中,以便在将来使用应用程序时无需下载该文件?
如果是这样,如果我更改了“myText.txt”,应用程序会知道获取新版本吗?
最后,如果文件确实存储在缓存中,那么这与HTML5中的本地存储有什么不同?
谢谢。

与HTML5存储的区别在于,用于客户端捆绑资源等的缓存纯粹是HTTP资源的标准浏览器缓存,它根据URL和HTTP缓存头自动缓存,而您将自己管理进入HTML5存储的内容。 - Chris Lercher
3个回答

5
  • 正如Daniel Kurka所提到的,资源可以内联在js文件(一个 *.cache.* 文件)中,这是编译好的GWT代码的一部分。
  • 并非所有客户端束中的资源都会被内联。例如,大型图像永远不会被内联,也可以用 @ImageOptions.preventInlining() 防止内联,并且外部文本资源也不会被内联。

两种情况的共同点是,结果都将在 *.cache.* 文件中,具有唯一的名称,每当源文件的内容发生更改时,它们会自动更改(但您必须重新编译GWT应用程序!)

这使得服务器能够使用适当的缓存HTTP标头(您必须自己设置!)来传递这些文件给客户端。对于客户端而言,这意味着它不仅可以缓存内容(即使没有设置这些标头,它也会这样做),而且还可以跳过询问服务器是否存在更新版本。

ClientBundles的最大优点是文件名会自动更改,最大的缺点是在资源更改时必须重新编译GWT应用程序。如果您不想这样做,那么最好使用其他方法来加载文件:您仍然可以使浏览器缓存任何您需要的文件(通过设置HTTP标头),但是当内容发生更改时,您必须小心地手动给它们一个新名称。


4
如果您希望其仅在需要时加载而不是作为编译JavaScript的一部分进行加载,则应使用外部文本资源。如果用户需要整个文件,请使用一个文本资源。如果用户只需要其中的某些部分,请将此文件拆分为单独的较小文件:仅在需要时才会加载请求的文件。外部文本资源可以像所有其他静态文件一样进行缓存。
参考链接:https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#TextResource

谢谢Andrei。你能解释一下“外部文本资源可以像所有其他静态文件一样被缓存”的意思吗?我希望实现这样的情况:一个大文件仅需要下载一次,然后以某种不可思议的方式存储在“缓存”中,这样在将来调用应用程序时,就不需要再次下载该文件。ClientBundle可以实现这个功能吗? - aez
有不同类型的ClientBundles。ExternalTextResource可以满足您的需求。允许浏览器缓存静态文件取决于您使用的服务器。对于Apache,您需要启用mod_expires。对于Appengine,您需要修改appengine-xml等。 - Andrei Volgin

3

客户绑定包中的文件会被嵌入到编译后的javascript中,不会单独下载。如果您想在给定时间下载资源,可以轻松使用请求构建器。

如果您不想立即下载该文件,但仍希望将其嵌入,请使用代码拆分并将捆绑包放入应用程序的另一部分中。


谢谢Daniel。所以,如果我在客户端包中有一个大的100MB文件,那么每次用户启动应用程序时,它都必须被下载(作为编译后的JavaScript的一部分)吗?我认为ClientBundle的目的是利用缓存,难道不是这样吗? - aez
clientbundle 不是关于缓存的问题,而是关于在你的 JavaScript 中直接拥有资源(这些资源将被缓存),但是一个 100MB 的资源不适合用 clientbundle(也不适合下载...)要使用服务调用来分割它! - Daniel Kurka
谷歌网站上说:“部署的GWT应用程序中的资源可以粗略地分为永不缓存的资源(.nocache.js)、永久缓存的资源(.cache.html)和其他所有资源(myapp.css)。ClientBundle接口将条目从其他所有类别移动到永久缓存类别中。” 所以在我看来,ClientBundle确实使用“缓存”,无论这是什么意思。 这会改变你的想法吗,丹尼尔? - aez
这正是我在上一条评论中所说的。 - Daniel Kurka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接