gwt代码拆分:测试片段是否已经加载有什么好处?

时间:2015-02-28 19:18:17

标签: gwt

GWT Code Splitting Dev Guide及其中建议的模块模式的上下文中定义了排除代码片段,我理解第一次调用静态Module.createAsync(final ModuleClient client)然后Module内的代码下载了类,后续对此静态函数的调用将不会再次下载相同的代码片段。

该模式进一步建议缓存INSTANCE类的Module以用于“对于在模块之后明确加载的任何代码”。

所以我的问题是:

  1. 从初始片段第一次调用后,每次调用Module.createAsync(final ModuleClient client)是否都会调用服务器来检查代码片段是否需要下载?或者是否在没有任何服务器调用开销的情况下调用onSuccess()

  2. 初始片段中的以下代码是否导致Module代码成为初始下载的一部分(即,不是排除片段)?

  3. >

    if (INSTANCE == null)
      Module.createAsync(new ModuleClient()
      {
        @Override
        public void onUnavailable(Throwable reason)
        {
          // Action in case of failure
        }
        @Override
        public void onSuccess(Module instance)
        {
          instance.showBigComplicatedStuff();
        }
      });
    else
      INSTANCE.showBigComplicatedStuff();
    

    换句话说:

    1. 初始片段子句中是否存在INSTANCE.showBigComplicatedStuff();会导致包含Module的{​​{1}}代码成为初始片段的一部分,还是会导致showBigComplicatedStuff()因为Modulenew Module()内(在Module.createAsync内)被调用,因此无论如何都是在一个独占片段中?

    2. 仅当GWT.runAsync有助于减少对服务器的不必要的异步调用时,这种第一次调用Module.createAsync的模式是什么? (同样,我了解那些最终的服务器调用不会再次下载相应的INSTANCE == null片段。)

1 个答案:

答案 0 :(得分:3)

您拥有的代码不完整 - 为什么您拥有INSTANCEinstance并不明显,如果INSTANCE是作为Module.createAsync的一部分生成的公共字段,则还可以执行其他操作填充它?我会尝试自己回答这两个问题,指出我在路上做出的任何假设

  1. 假设INSTANCE类型的对象永远不可能在GWT.runAsync之外创建,实例方法showBigComplicatedStuff除非已加载分割点,否则无法执行任何操作(因此至少有一个实例已经创建) - 编译器足够聪明,可以解决这个问题。但是,

  2. 空检查是没有意义的,正是你提到的原因 - 如果你明白没有服务器调用去获取新的GWT.runAsync片段,那么你认为异步服务器调用是什么发生在GWT.runAsync内?如果代码已下载且无需再次下载,则无需下载。

  3. 自页面加载以来第二次运行GWT.runAsync没有任何开销。如果正确实现了缓存,甚至在页面加载后第一次点击它再次应该是便宜/免费的(这意味着服务器不会被再次击中,但仍有费用将JS解析为内存)。

    因为GWT.runAsync在加载后没有服务器调用开销(因此INSTANCE不是null),所以您不必担心它。 GWT会注意到它已经拥有了所需的代码,并且不会再尝试下载它。


    即使没有所谓的完美&#39;缓存,这种行为都将成立。如果您正在设置缓存标头以便将<hashname>.cache.*文件缓存一年,那么第二次加载模块或分割点时,它将继续使用相同的本地结果而不会有网络流量。如果没有完美的缓存,但磁盘上的文件仍然相同,重新加载应用程序将导致304 Not Modified - 不是免费的,但不像再次下载那样昂贵。

    GWT应用程序(使用其中一个标准链接器)以appname.nocache.js文件开头 - 此文件包含上面提到的<hashname>字符串,只有在代码更改时才会更改,因此不得高速缓存以便可以发生代码更改,客户端立即看到更改。然后下载或读取给定属性集的初始片段(即&#39;哪个浏览器&#39; *&#39;哪个区域设置&#39; *&#39;哪些形式因素&#39;等)缓存为<hashname>.cache.js,然后当命中给定的分裂点<N>时,分割点将被提取为deferredjs/<hashname>/<N>.cache.js


    尽管如此,Module.createAsync事物背后的理论是异步工厂,所以你当然可以按照你描述的方式使用它。在这种情况下,如果只有一个实例很重要,我可能有一个getOrCreateAsync来执行模块类中的单例位 - 只要该类负责创建实例并提供它,它也可以总是提供它。这实际上取决于您如何使用实例,它包含的内容等等。