如何调试Ember CLI/Broccoli构建速度慢的问题

17

我的Ember CLI项目目前需要8-9秒才能构建完成,我希望了解其中的原因。该项目并不是很大(包括hbs和scss在内的app/下约有180个文件)。

这是我的brocfile:https://gist.github.com/samselikoff/874c90758bb2ce0bb210

即使我将整个Brocfile注释掉并仅导出app变量,构建仍然需要5-6秒。

我不太确定如何调试。这是我最慢的树日志:

构建成功 - 8874毫秒。

Slowest Trees                  | Total          
-------------------------------+----------------
TreeMerger (appAndDependencies)| 1286ms         
TreeMerger (vendor)            | 1275ms         
CompassCompiler                | 1204ms         
StaticCompiler                 | 1185ms         
TreeMerger (stylesAndVendor)   | 1151ms         
TreeMerger (allTrees)          | 706ms          
StaticCompiler                 | 625ms    

1
你是否在使用Windows系统?我曾经遇到一个问题,我的项目非常小,但是构建需要长达20秒的时间。后来发现是我的病毒扫描器干扰了构建过程。请查看Github上的这个帖子获取更多信息。 - sonikarc
@sonikarc 不是,我用的是Mac。谢谢你提供的链接。 - Sam Selikoff
2个回答

15

更新:如果您使用的是版本为0.1.0或更高版本的ember-cli,则这个技巧可能不再必要。现在的ember-cli会将文件链接起来而不是复制文件。(参见此链接) 在Windows或慢速磁盘上仍然可以获得性能提升。


Broccoli(ember-cli使用的构建工具)将其临时状态存储在文件系统中,因此它非常依赖于文件I/O。尽量减少public/vendor/bower_components/目录中文件的数量。这些文件夹中的所有文件都将每个重建周期至少复制一次。这些文件夹中的文件大小和数量会极大地影响性能。

基本上,每次更改文件时,Broccoli都会在<ember app>/tmp/内的许多目录之间复制文件。在您的bower_components/目录的情况下,它似乎正在复制每个文件不止一次。它需要这样做是因为您可能会在Brocfile.js中使用app.import('some.js'),还可能在SASS/LESS文件中使用@import "some.scss"。无法知道您实际需要哪些文件,因此它会复制所有文件。

如果从bower_components/vendor/中删除不必要的文件,您将会注意到更快的构建时间。

一个真实的例子

如果您安装highcharts.com#3.0.5的bower依赖项,则您还会在bower_components/目录中获得2829个特殊文件(198MB)。想象一下那里正在发生的不必要的文件系统读取和复制操作。

这是我清理后的目录结构的一部分:

$ find bower_components -type f | grep highcharts
bower_components/highcharts.com/js/highcharts-more.src.js
bower_components/highcharts.com/js/highcharts.src.js

请注意,只有.js文件保留了下来,我移除了其他所有的文件。这是2827个被删除的文件。Highcharts是一个极端的例子,但大多数依赖项的文件数量是你实际需要的5倍。

积极向前发展

ember-cli团队正在努力改进基础的broccoli生态系统性能。工作已经开始,一些真实世界的应用程序(具有大型树)正在看到性能改进,将重建时间从4秒减少到600毫秒。使用符号链接而不是复制显示出巨大的改进。

对于我们这些拥有大型应用程序、许多bower依赖项和许多哭泣的团队成员的人,需要一个立即的解决方案:

一个临时解决方案

保持你的bower_components/干净的一种方法是将依赖关系检入版本控制。这样可以轻松使用git clean清理目录:

bower install —-save d3
git add -—force bower_components/d3/d3.js # force, because bower_components/ is gitignored
git commit -m "Added d3.js"

// Brocfile.js
app.import('bower_components/d3/d3.js');
每次执行bower install时,您很可能会在目录中得到所有额外的垃圾文件。git clean可以轻松删除非版本控制的文件。
git clean -f -d -x bower_components/
ember serve

在执行这个操作后,单次重建(更改文件后的构建时间)从20秒降至3.5秒(我们有一个相当大的应用程序)。

如果您选择这条路,请不要忘记Ember需要的bower依赖项:

bower_components/ember/ember.js
bower_components/ember/ember.prod.js
bower_components/ember-cli-shims/app-shims.js
bower_components/ember-cli-test-loader/test-loader.js
bower_components/ember-data/ember-data.js
bower_components/ember-data/ember-data.prod.js
bower_components/ember-load-initializers/ember-load-initializers.js
bower_components/ember-resolver/dist/modules/ember-resolver.js
bower_components/jquery/dist/jquery.js
bower_components/loader/loader.js
bower_components/handlebars/handlebars.js
bower_components/handlebars/handlebars.runtime.js

这是给你的 git 命令:

bower install
git add -f bower_components/ember/ember.js bower_components/ember/ember.prod.js  bower_components/ember-cli-shims/app-shims.js  bower_components/ember-cli-test-loader/test-loader.js  bower_components/ember-data/ember-data.js  bower_components/ember-data/ember-data.prod.js  bower_components/ember-load-initializers/ember-load-initializers.js  bower_components/ember-resolver/dist/modules/ember-resolver.js  bower_components/jquery/dist/jquery.js  bower_components/loader/loader.js  bower_components/handlebars/handlebars.js bower_components/handlebars/handlebars.runtime.js
git commit -m "Added ember-cli dependencies"
git clean -f -d -x bower_components/

1
在IRC上指引我之后,我创建了一个脚本,基本上实现了相同的功能,而不会污染git存储库。它还有一些魔法,可以自动保留从Brocfile.js导入的文件。您可以在此处查看:https://gist.github.com/dschmidt/a68747348036fd6aa989(是的,我在bash脚本方面完全不擅长:P) - Dominik Schmidt
我对@DominikSchmidt的脚本的看法 https://gist.github.com/wrenoud/784dfcff244265f9593b我不想污染仓库。 - Weston
等一下,我找到了你的另一篇帖子,所以我会尝试 cmd > node C:/my/ember-cli/project/path/clean_ember-cli.js - Eric D. Johnson

0

除了 @tstirrat 的回答:

只有以管理员身份运行,才能使用符号链接文件(默认的SeCreateSymbolicLinkPrivilege标志)。尝试以管理员身份运行 cmd(或PowerShell),看看是否有帮助。

您可以使用本地策略配置为特定用户允许它。

从这里获取答案


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