Performance bottleneck with external source map sources #40054
Labels
Domain: Performance
Reports of unusually slow behavior
Fix Available
A PR has been opened for this issue
Needs Investigation
This issue needs a team member to investigate its status.
Milestone
TypeScript Version: 3.9.7
Search Terms: external source maps, performance, setSourceMapSource
Code
I am investigating Angular compiler performance and noticed an interesting performance cliff related to TypeScript's ability to map into external sources. External source map sources are used in
ngc
(Angular'stsc
) to map into the external.html
template files, using thets.createSourceMapSource
andts.setSourceMapRange
public APIs.During emit,
emitSourcePos
is used to build the source map, using a fast-path if no external source map source is used:TypeScript/src/compiler/emitter.ts
Lines 5290 to 5300 in a7d8011
With an external source map, however, the slow-path that calls into
setSourceMapSource
is run twice, for each emittedts.Node
. This calls intots.SourceMapGenerator.addSource
which manages the source indices per source map source, based on their canonicalized relative path:TypeScript/src/compiler/sourcemap.ts
Lines 52 to 69 in a7d8011
The path manipulation is somewhat expensive and it calls repeatedly into
ts.CompilerHost.getCanonicalFileName
, so its performance characteristics also have quite a significant impact.TypeScript/src/compiler/path.ts
Lines 817 to 832 in a7d8011
Using a program with the following characteristics (obtained with
tsc --diagnostics
):we're seeing 4.8 seconds spent in
emitSourcePos
usingngc
(of which 4.3 seconds is spent insetSourceMapSource
), where the full emit phase takes 13.4 seconds; i.e. source mapping takes 36% of emit (using a profiler, so there's some overhead there). More importantly, the slow path insetSourceMapSource
is responsible for 4.3/4.8 = ~90% overhead.Using Angular CLI it's much worse with
emitSourcePos
taking ~16s, given that thets.CompilerHost.getCanonicalFileName
implementation is a lot slower—that is for Angular itself to improve.Expected behavior:
The overhead in
setSourceMapSource
should not be 90% of total source mapping time.Actual behavior:
Using external source map sources does have a significant performance overhead, increasing source map times ten-fold or worse.
Playground Link:
n/a
Related Issues:
n/a
The text was updated successfully, but these errors were encountered: