Solvedangular cli 1.5 AOT by default performance tracking issue

Heya all,

When using Angular CLI 1.5 together with Angular 5.0.0, ng serve will default to using --aot=true. We added a new pipeline that should make AOT compilation much faster than it was with older CLI and Angular versions so we felt confident that AOT rebuild speeds should be much better.

Bigger projects can still have slow AOT rebuilds though. You can disable AOT by passing on the --no-aot (or --aot=false) flag, but if you have time I'd also like to ask for your help debugging remaining bottlenecks.

A good way to figure out how time is being spent in a rebuild is via CPU profiles. These show what functions are being called and how much time is being spent in each function.

This is how you can capture a CPU profile and share it here:

  • Make sure your project is using the following dependencies:
    • At least @angular/cli@1.5.0-rc.8.
    • At least @angular/core@5.0.0-rc.9, together with other @angular/* packages.
    • At least rxjs@5.5.2.
    • Exactly typescript@2.4.2, newer versions might work but this is the latest officially supported by @angular/compiler-cli.
  • Open chrome://inspect/#devices in chrome, and then click Open dedicated DevTools for Node. This will give you a window called Developer Tools - Node.js that we'll get back to in a second.
  • In your package.json, add the following NPM script:
    • "debug": "node--max_old_space_size=8192 --inspect --debug-brk ./node_modules/@angular/cli/bin/ng serve"
    • This script tells node to start Angular CLI with the node debugger, and also to raise the maximum memory limit.
  • Run npm run debug.
  • The Open dedicated DevTools for Node window should pop up. It is stopped on the very first line of Angular CLI. Click the Resume button in the upper left corner of that window:
    image
  • Wait until the initial build is finalized.
  • Open your apps main.ts file, add console.log(1); to the end of it and save. Do this 3 times.
    • Saving a file without code changes won't trigger trigger a real rebuild, we have to actually change code like adding a console.log.
    • The first few rebuilds can take longer than others, so we ignore them.
  • Now we will capture the CPU profile of a rebuild:
    • Go back to the Open dedicated DevTools for Node window.
    • Click the right-most tab, called Profiler.
    • Click Start.
    • Add another console.log(1); to main.ts and save it.
    • Wait until the rebuild finishes.
    • Click the Stop button in the profiler tab.
    • Wait until Profile 1 shows up on the left, and then click it (opening it can take some time for big projects).
  • You should see a chart. Zoom into it until you get all of it in the screen, take a screenshot and post it here.
    • If you don't see a chart, click the dropdown beneath Profiler and select Chart from there.
      image

    • This is how it looks like for a new project:
      image

  • Right click Profile 1, click Save. Upload it somewhere and link it here.

Then I can look at the CPU profile and see where time is being spent on your rebuild. Hopefully I can find new bottlenecks and make your builds faster.

Note: Sometimes the debugger doesn't disconnect after you quit the ng serve process. If you have to do this process more than once and get Unable to open devtools socket: address already in use when running npm run debug, open your process manager and kill any existing Node.js processes.

43 Answers

✔️Accepted Answer

Hi @istiti, @hccampos,

To answer your questions:

This breaking my heart

It's also breaking ours. We really pushed the limits of both compilers (webpack, ngc and tsc) to be able to set AOT by default, and we fell short on large projects.

Does this mean we need wait ABC for cli v2 to have correct rebuild aot time in big project, or hopely in near future 1.5x ?

Yes and no. We have a plan to remake the build system which will allow us to keep using webpack while also splitting your application in smaller pieces. When that's in, you should see shorter rebuild times (assuming you're following our best practices).

Do you have some advice on structure project in big project we need follow for aot?

Not yet, but this is something we're working on.

For example, in the past it has been mentioned that using barrels could hurt performance. Is that still the case? Always or only when using export * from './awesomepackage'

It is still the case, but we helped webpack improve on this and they're still improving. We now build CommonJS in development which also fixes this issue completely (we want to go back to ES2015 modules but won't until performance improves).

In this case though, the performance itself comes from generating factories. The barrel is not a factor anymore, so times reported in this issue come mostly from ngc itself.

How about path alises, do they hurt rebuild times?

No. Path aliases are done by typescript, and report times of typescript itself (which is used in JIT) is minimal. Path aliases happen in both JIT and AOT.

And inline templates vs separate files? Inline styles vs scss files?

This is where most of the time is being spent in ngc. Big templates are definitely a problem, but it's unclear without actually investigating the issue where exactly the time is spent and if it can be helped.


The real fix would be to have smaller applications, which will come in the new build system and ABC (when it's ready).

Other Answers:

"It's also breaking ours. We really pushed the limits of both compilers (webpack, ngc and tsc) to be able to set AOT by default, and we fell short on large projects."
Valiant effort, guys! Thanks for all the hard work, as always.

More Issues: