When we talk about build performance, it is important to understand that there are several build phases:
- cold build (booting your app up for the first time)
- warm build (booting your app up when cache was populated)
- rebuild (subsequent rebuilds that happen on file change)
Cold build is the slowest because the cache is not yet populated and the application is booting for the first time. Build time varies and depends on the number of dependencies that application has but ballpark should be around 5 seconds for small to middle size applications and around 15 seconds for large size applications.
Warm build is faster then cold one because the cache was populated already and it takes less time re-compute dependecies. Build time varies but ballpark should be around 2 seconds for small to middle size applications and around 10 seconds for large size applications.
Rebuild aims to be the fastest because it happens the most often. App/ JavaScript Rebuild time varies but ballpark should be around 200-300ms for small to middle size applications and up to 1 second for large size applications (200kloc js + 3000 modules).
- rebuild of JS in app/ <--- Largely our focus, as this is likely the most common.
- rebuild of CSS/Sass/Less in app/: largely depends on 3 factors
- the size of bower_components (we have plans to largely mitigate this one)
- which preprocessor is being used (libsass vs ruby-sass vs less vs ...)
- the amount of css
- rebuild of vendor/, bower_components/ <--- somewhat costly still, due to how slow available sourceMap Libraries are. We have WIP with a more v8/JIT friendly sourceMap lib, already showing some very nice improvements.
note these times are based on a posix box with and SSD, win32 unfortunately tends to be slower. As we continue to improve performance, both posix and win32 improve, hopefully future work will bring these platforms build times closer together.
If you see that application timings escape, there might be a problem.
Addons known to cause a slow down (but have not yet been addressed):
- any old non-patch based broccoli plugin
- ember-cli-component-css
- ember-browserify
- ... ?
Make sure to mention which type of the build seems to be the problem so we can help identify and fix issues faster.
My rebuilds are slow. (And I have anti-virus installed)
Our build-system assumes a relative fast/performant file-system (although, we continue to reduce IO related work). It is quite common for a Anti-virus to slow down IO.
Common issues:
- anti-virus scanning of /tmp/, oftentimes this can be avoided alltogether.
- anti-virus on-file-access re-scanning files, oftentimes this can be disabled for the app directory. or ember can be whitelisted.
My rebuilds are slow. (And I am using an encrypted thumb-drive to host my project)
These sorts of drives are notoriously slow. Although we continue to reduce our IO overahead, you will be running at a dis-advantage. Often-times, a much better alternative is hardware supported full-disk encryption, like on most OSX corpoerate laptops (mine included) use. This setup is both reasonably secure, and has negible impact on performance.
My JavaScript rebuilds are still slow.
please run
npm ls broccoli-funnel broccoli-merge-trees broccoli-filter broccoli-persistent-filter broccoli-concat broccoli-caching-writer
and ideally the following should be true (otherwise some upgrades may be required)
broccoli-funnelshould be at^1.0.1broccoli-merge-treesshould be at^1.1.0broccoli-persistent-filtershould be at^1.1.6broccoli-filteroften needs to be replaced withbroccoli-persistent-filter(we hope to re-merge the two eventually)broccoli-sourcemap-concatshould be at^2.0.2but will soon be replace bybroccoli-concat(we have just re-merged the two)broccoli-caching-writershould be at^2.2.1broccoli-concatshould be at^2.0.3broccoli-stewshould be at^1.2.0- likely more...
Up next we should check for old and deprecate plugins
npm ls broccoli-static-compilerthis should no longer be used, ratherbroccoli-funnelatv1.0.1should be used- ..
Up next we should look for not-yet-fixed plugins
npm ls ember-component-css(this plugin needs to be updated to not monkey patch ember-cli, as its monkey patching restores issues)
npm v3 made my build slow
Well what happened is npm v3 changed the module topology, this coupled with a misbehaving plugin may result in extra files (maybe all of node_modules) being pulled into the build. This is going to be slow.., the solution is to find the offending plugin, and upgrade (or report the issue if it is not yet fixed).
One such plugin is ember-cli-ic-ajax, which has been fixed. So please be sure
to upgrade.
Finding such plugins, we can use a series of DEBUG flags, to gain more insight
DEBUG=broccoli-funnel:Funnel*Addon* ember s should reveal if extra files are
being pulled into the build
My builds are slow, and the above Q/A hasn't helped
Please be sure to read this full document (including the tips and tricks bellow). If the issue persists, please report an issue.
Be sure to include:
npm versionnpm ls(as a gist)- ideally a reproduction
- we are aware some are unable to share apps (even privately), this may prove more difficult to debug. Although in some cases, consulting and proper IP related paprwork to allow sharing could enable improved debugging
My builds are slow for a reason not mentioned here
We would love a PR improving this guide.
We use heimdalljs-logger for logging, which supports the same usage as the de facto standard debug. Quite often this can be used to quickly discover obviously wrong things.
Usage:
DEBUG=<pattern> ember sDEBUG=* ember sfor all logging (this will be very erbose)DEBUG=ember-cli* ember sfor all ember-cli loggingDEBUG=broccoli* ember sfor all broccoli loggingDEBUG=broccoli*,ember-cli* ember sfor both broccoli and ember-cli loggin
The above patterns will be very verbose. But to make them even more verbose you
can set the log level via DEBUG_LEVEL
DEBUG=* DEBUG_LEVEL=debug ember s
To make them a bit less verbose, a currated set of performance related logging flags are:
DEBUG=broccoli-caching-writer:* ember sDEBUG=broccoli-funnel:* ember sDEBUG=broccoli-funnel:Funnel*Addon* ember sDEBUG=broccoli-merge-trees:ember sDEBUG=broccoli-merge-trees:TreeMerger* ember sDEBUG=broccoli-merge-trees:Addon* ember sDEBUG=broccoli-merge-trees:styles ember sDEBUG=broccoli-merge-trees:compileTemplates* ember sDEBUG=broccoli-merge-trees:compileTemplates* ember s
Because many plugins are used repeatedly it may be difficult to see the context for log entries. By default, 3 nodes of context are shown.
DEBUG_LEVEL=debug DEBUG=broccoli-merge-trees: ember build
broccoli-merge-trees: [TreeMerger (testFiles)#777 -> ConcatWithMaps#782 -> BroccoliMergeTrees#783] deriving patches
To show more (or fewer) lines of context, specify the environment variable
DEBUG_DEPTH.
DEBUG_DEPTH=5 DEBUG_LEVEL=debug DEBUG=broccoli-merge-trees: ember build
# => broccoli-merge-trees: [TreeMerger (allTrees)#1 -> BroccoliMergeTrees#668 -> TreeMerger (testFiles)#777 -> ConcatWithMaps#782 -> BroccoliMergeTrees#783]
[... ConcatWithMaps#782 -> BroccoliMergeTrees#783] means that the log entry
occurred in broccoli merge-trees node with id 783, whose parent was a concat
with maps node with id 782. These ids are shown in the visualization graph.
See Visualization for details.
... more on what to look for ...
To visualize build tree, we use graphviz. To
install it run brew install graphviz or download it directly from
here.
You will also need to install
broccoli-viz version 3.0.3 or
higher. npm install -g broccoli-viz@^3.0.3.
To generate visualization:
BROCCOLI_VIZ=true ember buildbroccoli-viz broccoli-viz.0.json > broccoli-viz.0.dotdot -Tpng broccoli-viz.0.dot > broccoli-viz.0.png
Each build will generate an additional graph, broccoli-viz.<build-number>.json
in-depth tooling, aimed to provide much deeper insight into the given build
dot: is the input to graphviz, allowing tree visualizationjson: more detailed counts and timings related to the corresponding build