perf(compiler-cli): detect semantic changes and their effect on an in…#39791
Closed
JoostK wants to merge 2 commits intoangular:masterfrom
Closed
perf(compiler-cli): detect semantic changes and their effect on an in…#39791JoostK wants to merge 2 commits intoangular:masterfrom
JoostK wants to merge 2 commits intoangular:masterfrom
Conversation
0e87841 to
e9274ae
Compare
…cremental rebuild In Angular programs, changing a file may require other files to be emitted as well due to implicit NgModule dependencies. For example, if the selector of a directive is changed then all components that have that directive in their compilation scope need to be recompiled, as the change of selector may affect the directive matching results. Until now, the compiler solved this problem using a single dependency graph. The implicit NgModule dependencies were represented in this graph, such that a changed file would correctly also cause other files to be re-emitted. This approach is limited in a few ways: 1. The file dependency graph is used to determine whether it is safe to reuse the analysis data of an Angular decorated class. This analysis data is invariant to unrelated changes to the NgModule scope, but because the single dependency graph also tracked the implicit NgModule dependencies the compiler had to consider analysis data as stale far more often than necessary. 2. It is typical for a change to e.g. a directive to not affect its public API—its selector, inputs, outputs, or exportAs clause—in which case there is no need to re-emit all declarations in scope, as their compilation output wouldn't have changed. This commit implements a mechanism by which the compiler is able to determine the impact of a change by comparing it to the prior compilation. To achieve this, a new graph is maintained that tracks all public API information of all Angular decorated symbols. During an incremental compilation this information is compared to the information that was captured in the most recently succeeded compilation. This determines the exact impact of the changes to the public API, which is then used to determine which files need to be re-emitted. Note that the file dependency graph remains, as it is still used to track the dependencies of analysis data. This graph does no longer track the implicit NgModule dependencies, which allows for better reuse of analysis data. This commit also fixes an incorrectness where a change to a declaration in NgModule `A` would not cause the declarations in NgModules that import from NgModule `A` to be re-emitted. This was intentionally incorrect as otherwise the performance of incremental rebuilds would have been far worse. This is no longer a concern, as the compiler is now able to only re-emit when actually necessary.
…n an incremental rebuild
e9274ae to
b55b80f
Compare
21 tasks
zarend
reviewed
Feb 23, 2021
| /** | ||
| * The various ways in which a change may affect the compilation. | ||
| */ | ||
| export enum Affects { |
Contributor
There was a problem hiding this comment.
super nit pick: the correct spelling is Effects :)
Member
Author
There was a problem hiding this comment.
I hope you haven't looked into these changes too much, as this was the initial prototype which did NgModule impact analysis. I'll close this PR to avoid confusion. This really was meant as the verb Affects here, though; this enum models the various ways in which a certain change affects the NgModule scope.
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…cremental rebuild
In Angular programs, changing a file may require other files to be
emitted as well due to implicit NgModule dependencies. For example, if
the selector of a directive is changed then all components that have
that directive in their compilation scope need to be recompiled, as the
change of selector may affect the directive matching results.
Until now, the compiler solved this problem using a single dependency
graph. The implicit NgModule dependencies were represented in this
graph, such that a changed file would correctly also cause other files
to be re-emitted. This approach is limited in a few ways:
reuse the analysis data of an Angular decorated class. This analysis
data is invariant to unrelated changes to the NgModule scope, but
because the single dependency graph also tracked the implicit
NgModule dependencies the compiler had to consider analysis data as
stale far more often than necessary.
public API—its selector, inputs, outputs, or exportAs clause—in which
case there is no need to re-emit all declarations in scope, as their
compilation output wouldn't have changed.
This commit implements a mechanism by which the compiler is able to
determine the impact of a change by comparing it to the prior
compilation. To achieve this, a new graph is maintained that tracks all
public API information of all Angular decorated symbols. During an
incremental compilation this information is compared to the information
that was captured in the most recently succeeded compilation. This
determines the exact impact of the changes to the public API, which
is then used to determine which files need to be re-emitted.
Note that the file dependency graph remains, as it is still used to
track the dependencies of analysis data. This graph does no longer track
the implicit NgModule dependencies, which allows for better reuse of
analysis data.
This commit also fixes an incorrectness where a change to a declaration
in NgModule
Awould not cause the declarations in NgModules thatimport from NgModule
Ato be re-emitted. This was intentionallyincorrect as otherwise the performance of incremental rebuilds would
have been far worse. This is no longer a concern, as the compiler is now
able to only re-emit when actually necessary.