如何加快gwt编译器的速度?


201

我们开始在我们的项目中大量使用GWT,并且GWT编译器的性能变得越来越令人讨厌。

我们将开始改变工作方式以减轻该问题,包括更加强调托管模式浏览器,这推迟了稍后运行GWT编译器的需求,但这带来了自身的风险,特别是直到比我们想要的要晚得多的时候,才真正的浏览器发现问题。

理想情况下,我们希望使GWT编译器本身更快-一分钟才能编译一个相当小的应用程序真是令人不快。但是,如果使用的是相当幼稚的方式,我们将使用编译方式,因此我希望我们可以快速轻松地获得收益。

我们目前正在从ant Ant目标中调用com.google.gwt.dev.Compiler作为Java应用程序,最大堆内存为256m,并且有大量堆栈空间。Ant会使用fork = true和最新的Java 6 JRE启动该编译器,以尝试利用Java6的改进性能。我们将主控制器类与应用程序类路径一起传递给编译器,然后关闭。

我们还能做什么以提高速度?我们可以给它更多的信息,以便花费更少的时间来发现要做的事情吗?

我知道我们只能告诉它仅针对一个浏览器进行编译,但是我们需要进行多浏览器测试,因此这并不实际。

此时欢迎所有建议。

Answers:


144

让我们从一个令人不安的事实开始:GWT编译器的性能确实很糟糕。您可以在这里和那里使用一些技巧,但不会获得明显更好的性能。

您可以通过在您的代码中插入以下代码来对特定的浏览器进行编译gwt.xml

<define-property name="user.agent" values="ie6,gecko,gecko1_8"></define-property>

或使用gwt 2.x语法,并且仅适用于一种浏览器:

<set-property name="user.agent" value="gecko1_8"/>

例如,这将仅针对IE和FF编译您的应用程序。如果您知道仅使用特定的浏览器进行测试,则可以使用此小技巧。

另一个选择:如果您使用多个语言环境,并且再次仅使用一个语言环境进行测试,则可以将它们全部注释掉,以便GWT使用默认语言环境,这可以节省编译时的额外开销。

底线:您不会在编译器性能上得到数量级的提高,但是可以放轻松一些,您可以在这里和那里节省几分钟。


3
对于GWT 2.0看来,您实际上是希望此语法指定用户代理:<set-property name =“ user.agent” value =“ gecko,gecko1_8” />
停泊

在gwt 2.2中没有壁虎。编译器指出“壁虎值先前未定义。处理元素'set-property'时发生意外异常”
uthark,2011年

将值设置为“ gecko1_8”仅适用于Firefox 1.5和更高版本的Firefox 2.2
eaykin 2011年

这个答案已经快两年了。随时对其进行编辑以阐明这一点。
Yuval Adam

6
2013年,仍然GWT的编译时间很糟糕,任何人都可以改善这个答案,GWT 2.5
Forhad 2013年

62

如果使用-localWorkers标志运行GWT编译器,则编译器将并行编译多个排列。这使您可以使用多核计算机的所有内核,例如-localWorkers 2将告诉编译器并行编译两个排列。您不会得到数量级的差异(并非编译器中的所有内容都是可并行化的),但是如果您要编译多个置换,这仍然是明显的加速。

如果您愿意使用GWT的主干版本,则可以对任何浏览器使用托管模式(进程外托管模式),从而可以缓解当前大多数托管模式问题。这似乎是GWT的发展方向-始终以托管模式进行开发,因为编译不太可能获得更快的幅度。


2
啊,localWorkers选项是个宝物,这是值得知道的。可悲的是,我们的大多数开发箱都是单核xeon。OOPHM看起来也很有前途。始终在下一版本中,它是...
skaffman

4
在具有多个核心的盒子上虚拟化编译环境;远程进入该虚拟机;使用-localWorkers执行命令行GWT编译,使用最少的locals和user.agents;确保托管虚拟机的框是要部署到的网络对等体。结合使用此功能,您可以在tomcat中部署时将编译时间缩短至30秒左右。另外,所有这些都可以用脚本编写。您还可以在本地计算机上进行开发,创建svn补丁程序,并让您的脚本使用某种类型的NFS或samba共享应用补丁程序,从而无需仅复制src差异文件。好极了!
kr。

NX客户端还是在有限的ADSL,电缆或WiFi连接上进行远程开发的庞大+++。另外,无论您在哪里使用wk上网,您始终保持同步
kr。

默认为maven构建中平台可用的CPU数量。所以没有为我加快速度。
keiki 2015年

55

尽管该条目非常老,并且您大多数人可能已经知道,但我认为值得一提的是GWT 2.x包含一个新的编译标志,该标志通过跳过优化来加快编译速度。您绝对不应该部署以这种方式编译的JavaScript,但是在非生产连续构建过程中可以节省时间。

只需将标志:-draftCompile添加到您的GWT编译器行即可。


3
我使用了该选项,在我们的项目中有时会失败,并出现一个奇怪的错误。因此请注意,有时编译可能因此无法工作。
维克

31

这是可以设置的user.agent值的列表

(因为我一直在结束了这里的时候,我搜索我应该设置,使其只生产一个置换镀铬这里添加此答案是:。 <set-property name="user.agent" value="safari"/>


我应该在哪里添加此set-property元素?我尝试将其添加到我的app.gwt.xml文件中的<module>元素的内部和外部,但是它不起作用。
亚历克斯·沃登

它放在您的模块ABC.gwt.xml文件中,其中ABC是您的模块名称。
格伦

30

在较新版本的GWT中(我相信,从2.3或2.4开始),您还可以添加

<collapse-all-properties />

到您的gwt.xml中以进行开发。这将告诉GWT编译器创建一个覆盖所有语言环境和浏览器的排列。因此,您仍然可以在所有浏览器和语言中进行测试,但仍仅编译单个排列


2
有趣的是...有什么缺点?
skaffman 2011年

编译处理所有浏览器和语言的单个排列仍然比仅处理一种浏览器和语言的单个排列花费更多的时间,但是根据我的经验,差异并不明显。(〜25%,更是我所看到的,但仍然是一个巨大的进步在编译多个排列)

我找不到与此相关的文档链接...可以链接到某些内容吗?
skaffman

尽管此标记可加快编译速度,但也会中断Super Dev Mode(至少在2.6中)的调试。chrome调试器中显示的源代码与已编译的js代码不同。因此,当我在某个Java方法中设置断点时,调试器将在另一个方法中停止。
damluar 2014年

18

您可以向构建中添加一个选项以进行生产:

-localWorkers 8–其中8是计算置换的并发线程数。您要做的就是将这个数字调整为更方便的数字。请参阅GWT编译性能(感谢Dennis Ich的评论)。

如果要编译到测试环境,则还可以使用:

-draftCompile 这样可以实现更快,但优化程度较低的编译

-optimize 0 不会优化您的代码(最大优化值为9)

使构建和托管模式的性能提高一倍以上的另一件事是使用了SSD磁盘(现在,托管模式的工作原理很吸引人)。这不是一个便宜的解决方案,但是取决于您使用GWT的时间和时间成本,这可能是值得的!

希望这对您有所帮助!


将本地工人设置为核心数量可能非常无用。参见以下内容供参考:josephmarques.wordpress.com/2010/07/30/…–
Dennis Ich

谢谢您发表评论Dennis。实际上,我有一个SSD并提供2G内存。当然,必须根据排列,内核,机器等的数量来调整localWorker的数量,具体取决于排列,核心,机器等的数量。在我的情况下,当我在笔记本电脑上编译并想在Web上浏览时,如果腾出2个内核。这只是一个例子。但是,将编辑我的帖子以包含您的想法。谢谢。
martins.tuga,2014年

14

GWT编译器正在执行大量代码分析,因此将很难加速它。 Google IO 2008的这次会议将使您很好地了解GWT正在进行的工作以及为什么需要这么长时间。

我的建议是尽可能使用托管模式进行开发,然后仅在要进行测试时才进行编译。这听起来确实像您已经找到的解决方案,但是基本上这就是为什么有托管模式的原因(嗯,就是调试)。

您可以加快GWT的编译速度,但只能针对某些浏览器进行编译,而不是GWT默认情况下的5种浏览器。如果要使用托管模式,请确保至少为两个浏览器进行编译。如果您针对单个浏览器进行编译,则会优化浏览器检测代码,然后托管模式将无法再使用。

为较少的浏览器配置编译的一种简单方法是创建一个从您的主模块继承的第二个模块:

<module rename-to="myproject">
  <inherits name="com.mycompany.MyProject"/>
  <!-- Compile for IE and Chrome -->
  <!-- If you compile for only one browser, the browser detection javascript
       is optimised away and then Hosted Mode doesn't work -->
  <set-property name="user.agent" value="ie6,safari"/>
</module>

如果rename-to属性设置相同,则输出文件将与完全编译时的文件相同


11
  • 将您的应用程序分为多个模块或入口点,然后仅在需要时重新编译。
  • 使用主干版本分析您的应用程序-它提供了您的编译故事。这可能与1.6编译器相关,也可能无关,但它可以指示发生了什么。

多个入口点应该可以工作,但模块不能工作,因为GWT始终检查与代码连接的所有内容并编译完整的最终结果。GWT框架对模块化原则是一团糟且令人遗憾。找不到一个可以重用GWT框架的好项目。
user1050755

4

对于GWT 2.x,我刚刚发现,如果您使用

<set-property name="user.agent" value="ie6"/>
<extend-property values="ie8,gecko1_8" name="user.agent"/>

您甚至可以指定多个排列。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.