Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

ngcc: do not parse tsconfig.json more than once #36882

Closed
mpk opened this issue May 1, 2020 · 14 comments
Closed

ngcc: do not parse tsconfig.json more than once #36882

mpk opened this issue May 1, 2020 · 14 comments

Comments

@mpk
Copy link

mpk commented May 1, 2020

馃悶 bug report

Affected Package

The issue is caused by package @angular/compiler-cli

Is this a regression?

Yes, the previous version in which this bug was not present was: 8.2

Description

(this issue was separated from issue #36874 (comment))

After upgrading Angular 8 to Angular 9 (and Ivy), I have a problem with Angular CLI being stuck at "0% compiling" for a few minutes.

In my app, I have 324 npm modules that should be compiled by NGCC. First ng serve after npm install takes some time before all of them are compiled and cached, but that's fine. However, subsequent serves are also very slow (~ 9 minutes).

I have done some digging and found out that for each npm module (before mainNgcc bails out early due to cache), the following line is run (mainNgcc -> getSharedSetup -> readConfiguration):
https://github.com/angular/angular/blob/master/packages/compiler-cli/src/perform_compile.ts#L197

This line parses and resolves application's tsconfig.json file (by walking through the entire project directory, which in my case is ~ 3700 files) and it takes about 1.1s to do so. However, since it is run for each npm module (in my case 324 modules), this results in 1.1s * 324 modules = 6 minutes delay before the actual application start compiling.

I think the tsconfig.json should be parsed and resolved only once to avoid this delay.

馃敩 Minimal Reproduction

Create Angular 9 application with many npm modules and large project structure.
Run npm start.

馃實 Your Environment

Angular Version:


Angular CLI: 9.1.4
Node: 12.14.0
OS: win32 x64

Angular: 9.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.801.1
@angular-devkit/build-angular     0.901.4
@angular-devkit/build-optimizer   0.901.4
@angular-devkit/build-webpack     0.901.4
@angular-devkit/core              8.1.1
@angular-devkit/schematics        8.1.1
@angular/cdk                      9.2.1
@angular/material                 9.2.1
@ngtools/webpack                  9.1.4
@schematics/angular               8.1.1
@schematics/update                0.901.4
rxjs                              6.5.5
typescript                        3.8.3
webpack                           4.42.0
@petebacondarwin
Copy link
Member

Thanks for creating this issue @mpk - I hope to look into it later this week.

@petebacondarwin petebacondarwin self-assigned this May 4, 2020
@mohyeid
Copy link

mohyeid commented May 5, 2020

Is this a duplicate of #36272?

@petebacondarwin petebacondarwin changed the title Angular CLI stuck at 0% compiling with large project ngcc: do not parse tsconfig.json more than once May 24, 2020
@petebacondarwin
Copy link
Member

Is this a duplicate of #36272?

Not really. There are a number of reasons why the build can be slow at 0%. This is one particular reason.

@mpk - I would like to understand why parsing the config file content (i.e. calling ts.parseJsonConfigFileContent()) requires the entire file-system to be processed. Would you be willing to share a reproduction with me so that I could debug it?

@petebacondarwin petebacondarwin added needs reproduction This issue needs a reproduction in order for the team to investigate further triage #1 labels May 24, 2020
@mpk
Copy link
Author

mpk commented May 26, 2020

@petebacondarwin I have created a project that demonstrates the problem: https://github.com/mpk/ng-many-components

  • The project has around 1000 components in many directories - this is important, because TS seems to spend a lot of time visiting those directories. When I generated components to a single directory, it was a lot faster.
  • To simulate many npm modules, I have imported ~180 Angular locale files to main.ts
  • On my machine, parseJsonConfigFileContent took 250-300ms to process every compiled module in this project

@petebacondarwin
Copy link
Member

I cloned this repo...
On my machine the readConfiguration() function is called 175 times at an average of ~50ms per call. So this does add an extra 8 secs to the build.

@petebacondarwin petebacondarwin added state: confirmed and removed needs reproduction This issue needs a reproduction in order for the team to investigate further labels Jun 3, 2020
petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jun 3, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves angular#36882
petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jun 3, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves angular#36882
@petebacondarwin
Copy link
Member

Hopefully #37417 will fix this for you. Once the CI has run, you should be able to try using the output from it, although you might need to update your project to v10 first.

atscott pushed a commit that referenced this issue Jun 4, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves #36882

PR Close #37417
@atscott atscott closed this as completed in 6e7bd93 Jun 4, 2020
@steverob2k
Copy link

Please can this be added to a v9 release.

@petebacondarwin
Copy link
Member

Looking into it... there should still be a 9.1.x release on Wednesday

petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jun 8, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Cherry-picked from angular#37417 (6e7bd93).

Resolves angular#36882
petebacondarwin added a commit to petebacondarwin/angular that referenced this issue Jun 8, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Cherry-picked from angular#37417 (6e7bd93).

Resolves angular#36882
@petebacondarwin
Copy link
Member

9.1.x is not the LTS branch - so I have created a separate PR for it: #37484

@steverob2k
Copy link

@petebacondarwin Thank you so much for this. Really appreciate your time and effort looking at this issue

@mpk
Copy link
Author

mpk commented Jun 12, 2020

@petebacondarwin Thank you for the fix, I have verified the 6 minute delay is gone and compilation times have returned to Angular 8 level.

@petebacondarwin
Copy link
Member

馃帀 I am really pleased. Thanks for the update.

@steverob2k
Copy link

Can also confirm that this has fixed the issue for me. Thanks once again.

ngwattcos pushed a commit to ngwattcos/angular that referenced this issue Jun 25, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves angular#36882

PR Close angular#37417
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 13, 2020
profanis pushed a commit to profanis/angular that referenced this issue Sep 5, 2020
This commit will store a cached copy of the parsed tsconfig
that can be reused if the tsconfig path is the same.

This will improve the ngcc "noop" case, where there is no processing
to do, when the entry-points have already been processed.
Previously we were parsing this config every time we checked for
entry-points to process, which can take up to seconds in some
cases.

Resolves angular#36882

PR Close angular#37417
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.