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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opening/editing project file causes 100% CPU usage by tsserver #29834

Closed
pqvst opened this issue Feb 6, 2019 · 4 comments · Fixed by #30411
Closed

Opening/editing project file causes 100% CPU usage by tsserver #29834

pqvst opened this issue Feb 6, 2019 · 4 comments · Fixed by #30411
Assignees
Labels
Bug A bug in TypeScript

Comments

@pqvst
Copy link

pqvst commented Feb 6, 2019

  • VSCode Version: 1.31.0-insider (1.31.0-insider) (also tested in latest non-insider release)
  • OS Version: macOS 10.14.2 (18C54)

Steps to Reproduce:

  1. Clone this repo: https://github.com/pqvst/vscode-cpu-issue-test
  2. Open the folder in VSCode
  3. Open browse.js
  4. tsserver CPU usage goes to 100% for a while
  5. Reopening the file or making any edit will again trigger high CPU usage

Expected results:
I expect to be able to work in my code base without having my fans go crazy.

Actual results:
Working in my code base causes my fans to go crazy.

Does this issue occur when all extensions are disabled?:
Yes

screenshot 2019-02-06 13 16 18

@pqvst pqvst changed the title Opening project file causes 100% CPU usage by tsserver Opening/editing project file causes 100% CPU usage by tsserver Feb 6, 2019
@roblourens roblourens assigned mjbvz and unassigned roblourens Feb 6, 2019
@mjbvz mjbvz transferred this issue from microsoft/vscode Feb 9, 2019
@mjbvz
Copy link
Contributor

mjbvz commented Feb 9, 2019

Thanks for the example project. I can't repo this however. @pqvst Have you perhaps configured the typescript.tsdk setting in VS Code so that we are using an older version of TypeScript for IntelliSense?

The 1 MB+ file makes this sound similar to #27960

@pqvst
Copy link
Author

pqvst commented Feb 9, 2019

In my regular instance of vscode I have typescript.tsdk configured to be my global npm typescript package. I am able to reproduce the issue with both 3.3.1 and 3.3.3. However, I have also reproduced the issue in a clean install of the Insider build as well (using the default typescript sdk).

Note that my CPU usage spikes both when opening the large file, but also when just opening a file that requires the large file.

I also just noticed that when I open the large file (data.js) then both tsserver and window CPU usage spikes like crazy:

image

Another note. If I comment out the code in browse.js that uses the required data file, then CPU usage is normal. Not problems whatsoever.

image

However, if I add more usage, then the CPU spike lasts much longer:

image

It's odd that you're not able to reproduce the issue though 🤔

@RyanCavanaugh RyanCavanaugh assigned sheetalkamat and unassigned mjbvz Feb 14, 2019
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Feb 14, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.4.0 milestone Feb 14, 2019
@sheetalkamat
Copy link
Member

I don't think this has anything to do with large file but the type of file and its semantic analysis or operations like quick info,error checking. So this seems like dup of #27960 but not quite since the outlining doesn't cause issue as yet but the root cause seems similar.

Info 134  [15:18:15.505] request:
    {"seq":9,"type":"request","command":"geterr","arguments":{"delay":0,"files":["c:/temp/vscode-cpu-issue-test/browse.js"]}}
Perf 135  [15:18:15.506] 9::geterr: async elapsed time (in milliseconds) 0.8629
Info 136  [15:18:15.506] event:
    {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","diagnostics":[]}}
Info 137  [15:18:15.513] event:
    {"seq":0,"type":"event","event":"semanticDiag","body":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","diagnostics":[]}}
Info 138  [15:18:27.873] event:
    {"seq":0,"type":"event","event":"suggestionDiag","body":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","diagnostics":[{"start":{"line":1,"offset":11},"end":{"line":1,"offset":28},"text":"File is a CommonJS module; it may be converted to an ES6 module.","code":80001,"category":"suggestion"},{"start":{"line":4,"offset":7},"end":{"line":4,"offset":11},"text":"'AByB' is declared but its value is never read.","code":6133,"category":"suggestion","reportsUnnecessary":true},{"start":{"line":5,"offset":7},"end":{"line":5,"offset":11},"text":"'AByC' is declared but its value is never read.","code":6133,"category":"suggestion","reportsUnnecessary":true},{"start":{"line":6,"offset":7},"end":{"line":6,"offset":11},"text":"'AByD' is declared but its value is never read.","code":6133,"category":"suggestion","reportsUnnecessary":true}]}}
Info 139  [15:18:27.873] event:
    {"seq":0,"type":"event","event":"requestCompleted","body":{"request_seq":9}}
Info 140  [15:19:59.906] request:
    {"seq":10,"type":"request","command":"quickinfo","arguments":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","line":4,"offset":21}}
Perf 141  [15:19:59.916] 10::quickinfo: elapsed time (in milliseconds) 10.1018
Info 142  [15:19:59.916] response:
    {"seq":0,"type":"response","command":"quickinfo","request_seq":10,"success":false,"message":"No content available."}
Info 143  [15:20:0.119] request:
    {"seq":11,"type":"request","command":"quickinfo","arguments":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","line":4,"offset":25}}
Perf 144  [15:20:0.861] 11::quickinfo: elapsed time (in milliseconds) 741.5116
Info 145  [15:20:0.861] response:
    {"seq":0,"type":"response","command":"quickinfo","request_seq":11,"success":true,"body":{"kind":"method","kindModifiers":"declare","start":{"line":4,"offset":22},"end":{"line":4,"offset":29},"displayString":"(method) LoDashImplicitWrapper<{ \"e0\": { \"a\": string; \"b\": string; \"c\": string; \"d\": string; \"e\": string; \"f\": string; \"g\": string; \"h\": string; \"i\": string; \"j\": string; \"k\": string; \"l\": string; \"m\": string; }; \"e1\": { \"a\": string; \"b\": string; \"c\": string; \"d\": string; \"e\": string; \"f\": string; ... 6 more ...; \"m\": string; }; ... 6103 more ...; \"e6105\": { ...; }; }>.groupBy<{\n    \"e0\": {\n        \"a\": string;\n        \"b\": string;\n        \"c\": string;\n        \"d\": string;\n        \"e\": string;\n        \"f\": string;\n        \"g\": string;\n        \"h\": string;\n        \"i\": string;\n        \"j\": string;\n        \"k\": string;\n        \"l\": string;\n        \"m\": string;\n    };\n    \"e1\": {\n        \"a\": string;\n        \"b\": string;\n        \"c\": string;\n        \"d\": string;\n        \"e\": string;\n        \"f\": string;\n        \"g\": string;\n        ... 5 more ...;\n        \"m\": string;\n    };\n    ... 6103 more ...;\n    \"e6105\": {\n        ...;\n    };\n}>(this: _.LoDashImplicitWrapper<...>, iteratee?: _.ValueIteratee<...>): _.LoDashImplicitWrapper<...> (+1 overload)","documentation":"","tags":[{"name":"see","text":"_.groupBy"},{"name":"see","text":"_.groupBy"}]}}
Info 146  [15:20:3.720] request:
    {"seq":12,"type":"request","command":"quickinfo","arguments":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","line":4,"offset":39}}
Info 147  [15:20:8.243] response:
    {"seq":0,"type":"response","command":"quickinfo","request_seq":12,"success":true,"body":{"canceled":true}}
Info 148  [15:20:8.245] request:
    {"seq":13,"type":"request","command":"quickinfo","arguments":{"file":"c:/temp/vscode-cpu-issue-test/browse.js","line":4,"offset":38}}
Perf 149  [15:20:10.349] 13::quickinfo: elapsed time (in milliseconds) 2104.7219
Info 150  [15:20:10.349] response:
    {"seq":0,"type":"response","command":"quickinfo","request_seq":13,"success":true,"body":{"kind":"method","kindModifiers":"declare","start":{"line":4,"offset":35},"end":{"line":4,"offset":44},"displayString":"(method) LoDashImplicitWrapper<Dictionary<({ \"a\": string; \"b\": string; \"c\": string; \"d\": string; \"e\": string; \"f\": string; \"g\": string; \"h\": string; \"i\": string; \"j\": string; \"k\": string; \"l\": string; \"m\": string; } | { \"a\": string; \"b\": string; \"c\": string; \"d\": string; \"e\": string; \"f\": string; ... 6 more ...; \"m\": string; } | ... 6103 more ... | { ...; })[]>>.mapValues<({\n    \"a\": string;\n    \"b\": string;\n    \"c\": string;\n    \"d\": string;\n    \"e\": string;\n    \"f\": string;\n    \"g\": string;\n    \"h\": string;\n    \"i\": string;\n    \"j\": string;\n    \"k\": string;\n    \"l\": string;\n    \"m\": string;\n} | {\n    \"a\": string;\n    \"b\": string;\n    \"c\": string;\n    \"d\": string;\n    \"e\": string;\n    \"f\": string;\n    \"g\": string;\n    ... 5 more ...;\n    \"m\": string;\n} | ... 6103 more ... | {\n    ...;\n})[], string[]>(this: _.LoDashImplicitWrapper<...>, callback: _.ObjectIterator<...>): _.LoDashImplicitWrapper<...> (+11 overloads)","documentation":"","tags":[{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues\nTODO: This would be better if we had a separate overload for obj: NumericDictionary that returned a NumericDictionary,\n  but TypeScript cannot select overload signatures based on number vs string index key type."},{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues\nTODO: This would be better if we had a separate overload for obj: NumericDictionary that returned a NumericDictionary,\n  but TypeScript cannot select overload signatures based on number vs string index key type."},{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues\nTODO: This would be better if we had a separate overload for obj: NumericDictionary that returned a NumericDictionary,\n  but TypeScript cannot select overload signatures based on number vs string index key type."},{"name":"see","text":"_.mapValues\nTODO: This would be better if we had a separate overload for obj: NumericDictionary that returned a NumericDictionary,\n  but TypeScript cannot select overload signatures based on number vs string index key type."},{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues\nTODO: This would be better if we had a separate overload for obj: NumericDictionary that returned a NumericDictionary,\n  but TypeScript cannot select overload signatures based on number vs string index key type."},{"name":"see","text":"_.mapValues"},{"name":"see","text":"_.mapValues"}]}}

@weswigham
Copy link
Member

#30411 should fix all the slowness caused by the big object type, however lodash introduces a checking perf penalty with its complex types that you should be aware of. They're very pedantically accurate, and, because of that, are relatively expensive to check (IIRC we have a few issues open to try to improve our perf while checking them, but I can't find them). #30411 should probably clear up the most noticeable delays for you, though, considering that union property creation was actually the bulk of the delays you'd witnessed, rather than within checking bits of lodash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants