typescript-go icon indicating copy to clipboard operation
typescript-go copied to clipboard

Sourcemap generation consuming significant resources while sourcemaps are disabled

Open aem opened this issue 1 month ago • 8 comments

Description

When running tsgo --build on a project with source maps and declaration maps disabled, a significant amount of CPU and memory is spent on what seemingly should be unused source map-related functions.

tsgo setup

// <root>/tsconfig.json
//  ...
    "declaration": true,
    "emitDeclarationOnly": true,
    "sourceMap": false,
    "declarationMap": false,
    "emit": false,
//  ...

tsgo version: 7.0.0-dev.20251204.1

Details

After migrating our monorepo to tsgo with a significant local performance improvement, I went to test the new setup in CI and discovered worse performance than [email protected] on a CI machine with 4 CPU cores and 16gb memory. I ran tsgo with profiling enabled (profiles attached below) and noticed (with the help of Claude) that source map emission accounted for ~60% of cumulative CPU time during compilation despite source maps and declaration maps both being disabled during the build:

         0     0% 90.69%    126.39s 29.24%  github.com/microsoft/typescript-go/internal/printer.(*Printer).emitSourceMapsAfterNode
         0     0% 90.69%    125.28s 28.99%  github.com/microsoft/typescript-go/internal/printer.(*Printer).emitSourceMapsBeforeNode

The memory profile looks much less interesting, I suspect the ~18GiB of memory consumed by our project is just related to having ~1mm LOC and heavy use of intersection types, but I'm surprised to see the source map printer consuming the majority of CPU time while all maps are disabled.

Profiles

82514-cpuprofile.pb.gz 82514-memprofile.pb.gz

aem avatar Dec 07 '25 17:12 aem

Image Image

jakebailey avatar Dec 08 '25 20:12 jakebailey

What is your full config? Do you have inlineSourceMaps enabled? Everything I'm reading implies this code should not be running if source maps are enabled.

Though, the perf here is certainly quite bad in general.

jakebailey avatar Dec 08 '25 20:12 jakebailey

No inline source maps enabled, and I assume since we're only emitting declaration files anyway that setting wouldn't apply? Full tsconfig is here!

{
  "compilerOptions": {
    "diagnostics": true,
    "allowJs": true,
    "tsBuildInfoFile": "build/root.tsbuildinfo",
    "outDir": "./build/",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "sourceMap": false,
    "declarationMap": false,
    "isolatedModules": true,
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "noEmit": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": false,
    "strictNullChecks": true,
    "target": "esnext",
    "paths": {
      "*": ["./src/*"]
    },
    "experimentalDecorators": true,
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ]
  },
  "exclude": [
    "**/node_modules",
    "**/build",
    "**/.*",
    // ...
  ],
  "include": [
    // ...
  ],
  "references": [
    { "path": "src" },
    { "path": "functionsV2" }
  ]
}

aem avatar Dec 08 '25 21:12 aem

There's no reason whatsoever why this code should even be active for you. It would be very helpful if there were a repro of this that were public (or, something we could give you an NDA for)

jakebailey avatar Dec 08 '25 21:12 jakebailey

I'll see if I can get a minimal repro working in something public this evening, otherwise I can chat with folks internally to see if we can get you access to the repo for a bit to try and debug!

aem avatar Dec 08 '25 21:12 aem

I copied our project structure into an empty project and pretty immediately noticed the issue. Somewhat embarrassingly, we had a project reference which was misconfigured to include all files in the repo, and had declaration maps turned on (we do need declaration maps turned on for this project but it should only include a handful of files, not the entire repo). There's probably no action on that front given I don't know how you'd reasonably enforce a constraint that would prevent this misconfiguration. Apologies for the noise given it's a misconfiguration, I know that can be annoying.

Having said that, is it worth keeping this issue open + renaming (or closing + opening a new issue) for the high performance cost of those source map generation functions?

aem avatar Dec 08 '25 22:12 aem

Probably, yes, though it just means we need to get another repo with dts source map emit enabled so we can go faster here.

We benefited greatly in TS when written in TS because the string encoding was the same, so this would be a simple add, but the new code has to be more careful. But, I know this code is wrong already, so...

jakebailey avatar Dec 08 '25 22:12 jakebailey

Makes sense. Let me see if I can minimally repro the performance diff between "declarationMaps": true and "declarationMaps": false and I'll update here if I can do so

aem avatar Dec 08 '25 22:12 aem