Improve initial build performance by reducing calls to synchronizeHostData
#100
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.
This PR improves initial build performance. Times vary but I've seen a 4s second build go to 2.5s and a 22s build go to 12s.
The issue is that ts-loader too aggressively increases each file's version number which was invalidating TypeScript's cache. There is a TS method called
synchronizeHostData
that is very expensive to run and is called all over the place. However, it has two ways to short-circuit. One is usinggetProjectVersion
and the other is by reading all of the files'version
property. This PR handles both. When the initial call togetEmitOutput
is run for the entry file, TypeScript essentially loads up the entire program at that point. All of the files are read from disk, put in memory, parsed, etc. After the entry file is done, webpack calls the loader for each of the dependent files. Previously we would increase the file'sversion
number at this point. However, in most cases, the content of the file is exactly the same. By checking if the content is the same and not increasing the file'sversion
we do not invalidate TypeScript's cache and it can emit the file much more efficiently. AdditionallygetProjectVersion
is used to gain a small performance increase (TS doesn't need to iterate each file'sversion
).The early call to
getCompilerOptionsDiagnostics
was also causingsynchronizeHostData
to run. I moved this to later in the process so it can use the cached data.One test broke with this change, but I believe I'm just going to update the test. The scenario is that a
.d.ts
is changed which causes errors in the program. Previously the bundle would be re-emitted in this case, but with these changes it won't be. I don't think this is a problem because nothing in the emit actually changes. It's actually a little more efficient.This partially addresses some of the points regarding initial build time in #78. It also addresses #56.
@blakeembrey