gwt代码拆分:测试片段是否已经加载有什么好处吗?
gwt code splitting: is there any benefit in testing whether fragment already loaded or not?
在 GWT Code Splitting Dev Guide 的上下文和其中定义排除代码片段的建议模块模式中,我了解到第一次调用静态 Module.createAsync(final ModuleClient client)
然后 [=12] 中的代码=] class 已下载,后续调用此静态函数将不会再次下载相同的代码片段。
该模式进一步建议为 "for any code that definitely loads after the module".
缓存 Module
class 的 INSTANCE
所以我的问题是:
初始片段第一次调用后,是否每次调用Module.createAsync(final ModuleClient client)
都会调用服务器检查是否需要下载代码片段?还是在没有任何服务器调用开销的情况下调用 onSuccess()
?
初始片段中的以下代码是否会导致 Module
代码成为初始下载的一部分(即,不是排除片段)?
>
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();
换句话说:
初始片段子句中 INSTANCE.showBigComplicatedStuff();
的存在是否导致包含 showBigComplicatedStuff()
的 Module
代码成为初始片段的一部分还是 Module
无论如何都会在独占片段中,因为 new Module()
在 Module.createAsync
内调用(即在 GWT.runAsync
内)?
这种仅在 INSTANCE == null
时才第一次调用 Module.createAsync
的模式是否有助于减少对服务器的不必要的异步调用? (同样,我知道那些最终的服务器调用不会再次下载相应的 Module
片段)。
您的代码不完整 - 为什么您有 INSTANCE
和 instance
并不明显,如果 INSTANCE 是作为 [=61] 的一部分生成的 public 字段=],还有什么可以填充它吗?我将尝试自己回答这两个问题,并指出我在此过程中所做的任何假设
假设永远不可能在 GWT.runAsync
之外创建 INSTANCE 类型的 objects,实例方法 showBigComplicatedStuff
不能做任何事情,除非那个分割点有已加载(因此至少创建了一个实例)——编译器足够聪明,可以解决这个问题。然而,
空检查毫无意义,正是因为你提到的原因 - 如果你明白没有服务器调用去获取新的 GWT.runAsync
片段,那么异步服务器调用什么你认为 GWT.runAsync
里面发生了什么?如果代码已经下载了,不需要再次下载,那就没有什么可下载的了。
页面加载后第二次 运行 和 GWT.runAsync
没有开销。如果缓存实现正确,即使在页面加载后第一次点击再次应该是cheap/free(意味着服务器不会再次被点击,但是有仍然是将 JS 解析到内存中的开销。
因此,由于 GWT.runAsync
在加载后没有服务器调用开销(因此 INSTANCE
是非 null
),您不必担心它。 GWT 会注意到它已经拥有所需的代码,并且不会尝试再次下载它。
即使没有 so-called 'perfect' 缓存,这个行为也会成立。如果你碰巧设置了缓存 headers 以便你的 <hashname>.cache.*
文件被缓存一年,那么第二次加载模块或分割点时,它将继续使用相同的本地结果没有网络流量。如果没有完美的缓存但文件在磁盘上仍然相同,则重新加载应用程序将导致 304 Not Modified
- 不是免费的,但不像再次下载那么昂贵。
GWT 应用程序(使用标准链接器之一)以 appname.nocache.js
文件开始 - 此文件包含上面提到的 <hashname>
字符串,这些字符串仅在代码更改时更改,因此不得缓存以便可以发生代码更改,客户端会立即看到更改。给定属性集的初始片段(即 'which browser' * 'which locale' * 'which form factor' 等)然后作为 <hashname>.cache.js
从缓存中下载或读取,然后当给定的分割点 <N>
被击中,分割点被提取为 deferredjs/<hashname>/<N>.cache.js
。
综上所述,Module.createAsync
背后的理论是成为一个异步工厂,因此您当然可以按照您描述的方式使用它。在这种情况下,尽管只有一个实例很重要,但我可能有一个 getOrCreateAsync
来执行模块 class 中的单例位 - 只要 class 负责创建实例并提供它,它还不如总是提供它。这实际上取决于您如何使用实例、它包含的内容等。
在 GWT Code Splitting Dev Guide 的上下文和其中定义排除代码片段的建议模块模式中,我了解到第一次调用静态 Module.createAsync(final ModuleClient client)
然后 [=12] 中的代码=] class 已下载,后续调用此静态函数将不会再次下载相同的代码片段。
该模式进一步建议为 "for any code that definitely loads after the module".
缓存Module
class 的 INSTANCE
所以我的问题是:
初始片段第一次调用后,是否每次调用
Module.createAsync(final ModuleClient client)
都会调用服务器检查是否需要下载代码片段?还是在没有任何服务器调用开销的情况下调用onSuccess()
?初始片段中的以下代码是否会导致
Module
代码成为初始下载的一部分(即,不是排除片段)?
>
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();
换句话说:
初始片段子句中
INSTANCE.showBigComplicatedStuff();
的存在是否导致包含showBigComplicatedStuff()
的Module
代码成为初始片段的一部分还是Module
无论如何都会在独占片段中,因为new Module()
在Module.createAsync
内调用(即在GWT.runAsync
内)?这种仅在
INSTANCE == null
时才第一次调用Module.createAsync
的模式是否有助于减少对服务器的不必要的异步调用? (同样,我知道那些最终的服务器调用不会再次下载相应的Module
片段)。
您的代码不完整 - 为什么您有 INSTANCE
和 instance
并不明显,如果 INSTANCE 是作为 [=61] 的一部分生成的 public 字段=],还有什么可以填充它吗?我将尝试自己回答这两个问题,并指出我在此过程中所做的任何假设
假设永远不可能在
GWT.runAsync
之外创建 INSTANCE 类型的 objects,实例方法showBigComplicatedStuff
不能做任何事情,除非那个分割点有已加载(因此至少创建了一个实例)——编译器足够聪明,可以解决这个问题。然而,空检查毫无意义,正是因为你提到的原因 - 如果你明白没有服务器调用去获取新的
GWT.runAsync
片段,那么异步服务器调用什么你认为GWT.runAsync
里面发生了什么?如果代码已经下载了,不需要再次下载,那就没有什么可下载的了。
页面加载后第二次 运行 和 GWT.runAsync
没有开销。如果缓存实现正确,即使在页面加载后第一次点击再次应该是cheap/free(意味着服务器不会再次被点击,但是有仍然是将 JS 解析到内存中的开销。
因此,由于 GWT.runAsync
在加载后没有服务器调用开销(因此 INSTANCE
是非 null
),您不必担心它。 GWT 会注意到它已经拥有所需的代码,并且不会尝试再次下载它。
即使没有 so-called 'perfect' 缓存,这个行为也会成立。如果你碰巧设置了缓存 headers 以便你的 <hashname>.cache.*
文件被缓存一年,那么第二次加载模块或分割点时,它将继续使用相同的本地结果没有网络流量。如果没有完美的缓存但文件在磁盘上仍然相同,则重新加载应用程序将导致 304 Not Modified
- 不是免费的,但不像再次下载那么昂贵。
GWT 应用程序(使用标准链接器之一)以 appname.nocache.js
文件开始 - 此文件包含上面提到的 <hashname>
字符串,这些字符串仅在代码更改时更改,因此不得缓存以便可以发生代码更改,客户端会立即看到更改。给定属性集的初始片段(即 'which browser' * 'which locale' * 'which form factor' 等)然后作为 <hashname>.cache.js
从缓存中下载或读取,然后当给定的分割点 <N>
被击中,分割点被提取为 deferredjs/<hashname>/<N>.cache.js
。
综上所述,Module.createAsync
背后的理论是成为一个异步工厂,因此您当然可以按照您描述的方式使用它。在这种情况下,尽管只有一个实例很重要,但我可能有一个 getOrCreateAsync
来执行模块 class 中的单例位 - 只要 class 负责创建实例并提供它,它还不如总是提供它。这实际上取决于您如何使用实例、它包含的内容等。