【问题标题】:How does GWT ClientBundle caching work?GWT ClientBundle 缓存如何工作?
【发布时间】:2012-09-29 11:37:45
【问题描述】:

我试图更好地理解 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 存储的内容。

标签: gwt clientbundle


【解决方案1】:
  • 正如 Daniel Kurka 已经提到的,资源可以内联在 js 文件(*.cache.* 文件)中,其余已编译 GWT 代码所在的位置。
  • 客户端捆绑包中的所有资源都不会发生内联。例如。大图像永远不会内联,也可以使用@ImageOptions.preventInlining() 来防止,ExternalTextResources 不会发生这种情况。

这两种情况的共同点是,结果将保存在 *.cache.* 文件中,其唯一名称会在源文件内容更改时自动更改(不过,您必须重新编译 GWT 应用程序!)

这允许服务器使用appropriate caching HTTP headers 传递这些文件(您必须自己设置!)对于客户端,这意味着它不仅能够缓存内容(无论如何它都会缓存内容,即使没有设置这些标头),但它甚至可以跳过询问服务器是否存在更新的版本。

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

【讨论】:

    【解决方案2】:

    如果您希望按需加载而不是作为已编译 JavaScript 的一部分,则应使用外部文本资源。

    https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#TextResource

    如果您的用户需要整个文件,请使用一个文本资源。如果用户需要其中的一部分,请将此文件拆分为单独的较小文件:仅在需要时加载请求的文件。

    外部文本资源可以像所有其他静态文件一样被缓存。

    【讨论】:

    • 谢谢安德烈。您能否解释一下“可以像所有其他静态文件一样缓存外部文本资源”是什么意思?我希望实现一个大文件只下载一次,然后以某种方式神奇地存储在“缓存”中的情况,这样以后调用应用程序时,就不需要再次下载文件了。 ClientBundle 会给我吗?
    • 有不同类型的 ClientBundle。 ExternalTextResource 可以满足您的需求。允许浏览器缓存静态文件取决于您使用的服务器。对于 Apache,您启用 mod_expires。对于 Appengine,您修改 appengine-xml。等等。
    【解决方案3】:

    clientbundle 中的文件会内联到您编译的 javascript 中。它们不会单独下载。如果您想在给定时间下载资源,您可以轻松地使用请求生成器。

    如果您不想立即下载文件但仍想内联它,您可以使用代码拆分并将包放入应用程序的另一部分。

    【讨论】:

    • 谢谢丹尼尔。因此,如果我的客户端包中有一个 100MB 的大文件,那么每次用户启动应用程序时都必须下载它(作为已编译 javascript 的一部分)?我认为 ClientBundle 的重点是利用缓存?
    • clientbundle 不是关于缓存,而是关于直接在您的 javascript 中拥有资源(将被缓存),但是 100 MB 的资源不适合 clientbundle(也不适合下载.. .) 将其与服务调用分开!
    • Google 网站说“部署的 GWT 应用程序中的资源可以大致分为永不缓存的资源 (.nocache.js)、永远缓存的资源 (.cache.html) 和其他所有资源 ( myapp.css)。ClientBundle 接口将条目从所有其他类别移动到永久缓存类别中。”因此,在我看来,ClientBundle 确实确实使用了“缓存”,无论它到底是什么。这会改变你的想法吗,丹尼尔?
    • 这正是我在上一条评论中所说的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 2016-02-15
    • 2014-10-06
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多