Description
I'm experiencing the same issue. With
4.5.2
it takes 2 minutes to simply load a type hint on hover (Controller
fromreact-hook-form
in this particular case). Our project is indeed huge, but the same operation with vs code's built-in4.4.3
is instant.I have no idea what's happening under the hood, but these are the two things from the server log that look very slow in 4.52:
"command":"geterr"
- almost two minutes until"event":"requestCompleted"
against ~10ms for 4.4.344::encodedSemanticClassifications-full: elapsed time (in milliseconds) 109280.8950
against less than 1s first time and less than 10ms later for 4.4.3Part of TS 4.5.2 server log
Info 2001 [19:47:33.826] request: {"seq":41,"type":"request","command":"geterr","arguments":{"delay":0,"files":["/Users/aleksei.tsikov/git/project/src/Component.tsx"]}} Perf 2002 [19:47:33.827] 41::geterr: async elapsed time (in milliseconds) 0.3917 Info 2003 [19:47:33.828] event: {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","diagnostics":[]}} Info 2004 [19:49:29.994] event: {"seq":0,"type":"event","event":"requestCompleted","body":{"request_seq":41}} Info 2005 [19:49:29.996] request: {"seq":42,"type":"request","command":"getApplicableRefactors","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","startLine":1,"startOffset":1,"endLine":1,"endOffset":1}} Perf 2006 [19:49:30.009] 42::getApplicableRefactors: elapsed time (in milliseconds) 13.2598 Info 2007 [19:49:30.009] response: {"seq":0,"type":"response","command":"getApplicableRefactors","request_seq":42,"success":true,"body":[{"name":"Convert export","description":"Convert default export to named export","actions":[{"name":"Convert default export to named export","description":"Convert default export to named export","kind":"refactor.rewrite.export.named","notApplicableReason":"Could not find export statement"},{"name":"Convert named export to default export","description":"Convert named export to default export","kind":"refactor.rewrite.export.default","notApplicableReason":"Could not find export statement"}]},{"name":"Convert import","description":"Convert namespace import to named imports","actions":[{"name":"Convert namespace import to named imports","description":"Convert namespace import to named imports","kind":"refactor.rewrite.import.named","notApplicableReason":"Selection is not an import declaration."}]},{"name":"Convert import","description":"Convert named imports to namespace import","actions":[{"name":"Convert named imports to namespace import","description":"Convert named imports to namespace import","kind":"refactor.rewrite.import.namespace","notApplicableReason":"Selection is not an import declaration."}]},{"name":"Extract Symbol","description":"Extract function","actions":[{"name":"Extract Function","description":"Extract function","kind":"refactor.extract.function","notApplicableReason":"Cannot extract empty range."}]},{"name":"Extract Symbol","description":"Extract constant","actions":[{"name":"Extract Constant","description":"Extract constant","kind":"refactor.extract.constant","notApplicableReason":"Cannot extract empty range."}]},{"name":"Extract type","description":"Extract type","actions":[{"name":"Extract to typedef","description":"Extract to typedef","kind":"refactor.extract.typedef","notApplicableReason":"Selection is not a valid type node"},{"name":"Extract to type alias","description":"Extract to type alias","kind":"refactor.extract.type","notApplicableReason":"Selection is not a valid type node"},{"name":"Extract to interface","description":"Extract to interface","kind":"refactor.extract.interface","notApplicableReason":"Selection is not a valid type node"}]},{"name":"Move to a new file","description":"Move to a new file","actions":[{"name":"Move to a new file","description":"Move to a new file","kind":"refactor.move.newFile","notApplicableReason":"Selection is not a valid statement or statements"}]},{"name":"Add or remove braces in an arrow function","description":"Add or remove braces in an arrow function","actions":[{"name":"Add braces to arrow function","description":"Add braces to arrow function","kind":"refactor.rewrite.arrow.braces.add","notApplicableReason":"Could not find a containing arrow function"},{"name":"Remove braces from arrow function","description":"Remove braces from arrow function","kind":"refactor.rewrite.arrow.braces.remove","notApplicableReason":"Could not find a containing arrow function"}]},{"name":"Convert to template string","description":"Convert to template string","actions":[{"name":"Convert to template string","description":"Convert to template string","kind":"refactor.rewrite.string","notApplicableReason":"Can only convert string concatenation"}]},{"name":"Infer function return type","description":"Infer function return type","actions":[{"name":"Infer function return type","description":"Infer function return type","kind":"refactor.rewrite.function.returnType","notApplicableReason":"Return type must be inferred from a function"}]}]} Info 2008 [19:49:30.009] request: {"seq":43,"type":"request","command":"projectInfo","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","needFileNameList":false}} Perf 2009 [19:49:30.009] 43::projectInfo: elapsed time (in milliseconds) 0.1021 Info 2010 [19:49:30.009] response: {"seq":0,"type":"response","command":"projectInfo","request_seq":43,"success":true,"body":{"configFileName":"/Users/aleksei.tsikov/git/project/tsconfig.json","languageServiceDisabled":false}} Info 2011 [19:49:30.011] request: {"seq":44,"type":"request","command":"encodedSemanticClassifications-full","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","start":1277,"length":3642,"format":"2020"}} Perf 2012 [19:51:19.295] 44::encodedSemanticClassifications-full: elapsed time (in milliseconds) 109280.8950 Info 2013 [19:51:19.295] response: {"seq":0,"type":"response","command":"encodedSemanticClassifications-full","request_seq":44,"success":true,"body":{"spans":[1281,8,2561,1312,6,2561,1342,8,2561,1368,6,2561,1403,29,2825,1436,11,1793,1449,11,1536,1463,17,1544,1496,11,1792,1678,11,1792,1702,5,1537,1712,5,2561,1720,4,1536,1728,15,2561,1769,16,2057,1787,3,1536,1791,5,1536,1803,5,1793,1810,15,1793,1844,5,2857,1851,12,2857,1865,7,2089,1874,8,2857,1887,7,2816,1895,10,1536,1913,13,2561,1936,9,2561,1947,15,1792,1970,8,2561,1980,8,2816,1989,10,2816,2004,4,272,2023,6,2561,2031,10,2816,2046,4,272,2066,4,2561,2100,11,2560,2113,5,2857,2120,4,2089,2126,6,2089,2137,11,2816,2150,6,1793,2158,10,1536,2177,3,2056,2181,4,2560,2186,23,3072,2218,9,2561,2229,6,1792,2236,9,2560,2253,8,2561,2263,6,1792,2270,8,2560,2279,7,3088,2296,6,2561,2304,6,1792,2311,6,2560,2318,7,3088,2350,12,2089,2365,4,2088,2371,4,2560,2393,11,2089,2406,19,2089,2430,13,2816,2444,12,2088,2467,11,2089,2481,7,2816,2501,5,1792,2514,3,3088,2518,8,1793,2533,5,2561,2540,8,1792,2549,3,2560,2554,5,2561,2561,8,1792,2570,5,2560,2586,5,1792,2607,9,2089,2619,5,2856,2646,8,2089,2657,5,2856,2800,15,1792,2868,7,2088,2933,5,1793,3044,11,2088,3288,7,2088,3348,5,1793,3475,5,1792,3481,5,2560,3514,5,1793,3549,8,2089,3560,10,2816,3571,5,1792,3598,5,1792,3604,8,3072,3613,8,2088,3641,8,2856,3660,7,2816,3668,8,2088,3789,7,2088,3847,5,1793,3999,6,2561,4007,8,2088,4035,5,2561,4042,8,2816,4051,8,2088,4107,5,1792,4113,5,2560,4146,5,1793,4175,5,1792,4181,8,3072,4190,10,2816,4201,5,1792,4381,12,2856,4394,10,1793,4408,5,2856,4414,10,1792,4475,9,2088,4618,29,2824,4648,6,2088,4673,11,2088,4705,7,2056,4754,6,2088,4865,19,2088],"endOfLineState":0}} Info 2014 [19:51:19.297] request: {"seq":47,"type":"request","command":"provideInlayHints","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","start":714,"length":4205}} Perf 2015 [19:51:19.350] 47::provideInlayHints: elapsed time (in milliseconds) 52.9589 Info 2016 [19:51:19.350] response: {"seq":0,"type":"response","command":"provideInlayHints","request_seq":47,"success":true,"body":[{"text":": PropsWithChildren<CellProps...","position":{"line":36,"offset":21},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":36,"offset":22},"kind":"Type","whitespaceBefore":true},{"text":"date:","position":{"line":36,"offset":56},"kind":"Parameter","whitespaceAfter":true},{"text":": PropsWithChildren<CellProps...","position":{"line":49,"offset":21},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":49,"offset":22},"kind":"Type","whitespaceBefore":true},{"text":"value:","position":{"line":50,"offset":34},"kind":"Parameter","whitespaceAfter":true},{"text":": (queryStatus: QueryStatus) ...","position":{"line":63,"offset":36},"kind":"Type","whitespaceBefore":true},{"text":": Props","position":{"line":79,"offset":72},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":79,"offset":73},"kind":"Type","whitespaceBefore":true},{"text":"props:","position":{"line":80,"offset":74},"kind":"Parameter","whitespaceAfter":true},{"text":"date:","position":{"line":83,"offset":26},"kind":"Parameter","whitespaceAfter":true},{"text":"amount:","position":{"line":83,"offset":50},"kind":"Parameter","whitespaceAfter":true},{"text":"date:","position":{"line":83,"offset":37},"kind":"Parameter","whitespaceAfter":true},{"text":"date:","position":{"line":84,"offset":26},"kind":"Parameter","whitespaceAfter":true},{"text":"mutationFn:","position":{"line":89,"offset":60},"kind":"Parameter","whitespaceAfter":true},{"text":": AxiosPromise<RevPTransactio...","position":{"line":89,"offset":80},"kind":"Type","whitespaceBefore":true},{"text":": RevPTransaction[]","position":{"line":97,"offset":21},"kind":"Type","whitespaceBefore":true},{"text":"data:","position":{"line":99,"offset":62},"kind":"Parameter","whitespaceAfter":true},{"text":": { label: string; value: str...","position":{"line":101,"offset":20},"kind":"Type","whitespaceBefore":true},{"text":"factory:","position":{"line":102,"offset":5},"kind":"Parameter","whitespaceAfter":true},{"text":"deps:","position":{"line":103,"offset":5},"kind":"Parameter","whitespaceAfter":true},{"text":": { label: string; value: str...","position":{"line":102,"offset":7},"kind":"Type","whitespaceBefore":true},{"text":"callbackfn:","position":{"line":102,"offset":29},"kind":"Parameter","whitespaceAfter":true},{"text":": Card","position":{"line":102,"offset":37},"kind":"Type","whitespaceBefore":true},{"text":": string","position":{"line":106,"offset":18},"kind":"Type","whitespaceBefore":true},{"text":"name:","position":{"line":106,"offset":27},"kind":"Parameter","whitespaceAfter":true},{"text":": Date","position":{"line":107,"offset":17},"kind":"Type","whitespaceBefore":true},{"text":"name:","position":{"line":107,"offset":26},"kind":"Parameter","whitespaceAfter":true},{"text":": { field: ControllerRenderPr...","position":{"line":117,"offset":33},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":117,"offset":34},"kind":"Type","whitespaceBefore":true},{"text":": { field: ControllerRenderPr...","position":{"line":132,"offset":31},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":132,"offset":32},"kind":"Type","whitespaceBefore":true},{"text":": Date | null","position":{"line":137,"offset":32},"kind":"Type","whitespaceBefore":true},{"text":": Date","position":{"line":138,"offset":33},"kind":"Type","whitespaceBefore":true},{"text":"date:","position":{"line":138,"offset":47},"kind":"Parameter","whitespaceAfter":true},{"text":"...event:","position":{"line":140,"offset":34},"kind":"Parameter","whitespaceAfter":true},{"text":"name:","position":{"line":141,"offset":28},"kind":"Parameter","whitespaceAfter":true},{"text":"value:","position":{"line":141,"offset":38},"kind":"Parameter","whitespaceAfter":true},{"text":"date:","position":{"line":141,"offset":46},"kind":"Parameter","whitespaceAfter":true},{"text":"amount:","position":{"line":141,"offset":56},"kind":"Parameter","whitespaceAfter":true},{"text":": { field: ControllerRenderPr...","position":{"line":149,"offset":31},"kind":"Type","whitespaceBefore":true},{"text":": Element","position":{"line":149,"offset":32},"kind":"Type","whitespaceBefore":true},{"text":"date:","position":{"line":155,"offset":35},"kind":"Parameter","whitespaceAfter":true},{"text":"amount:","position":{"line":155,"offset":45},"kind":"Parameter","whitespaceAfter":true},{"text":": Date | null","position":{"line":158,"offset":32},"kind":"Type","whitespaceBefore":true},{"text":"...event:","position":{"line":159,"offset":34},"kind":"Parameter","whitespaceAfter":true},{"text":"date:","position":{"line":159,"offset":45},"kind":"Parameter","whitespaceAfter":true},{"text":"onValid:","position":{"line":168,"offset":35},"kind":"Parameter","whitespaceAfter":true},{"text":": { cardToken: string; dateFr...","position":{"line":168,"offset":45},"kind":"Type","whitespaceBefore":true},{"text":"variables:","position":{"line":168,"offset":55},"kind":"Parameter","whitespaceAfter":true},{"text":"queryStatus:","position":{"line":178,"offset":55},"kind":"Parameter","whitespaceAfter":true}]} Info 2017 [19:51:19.350] request: {"seq":48,"type":"request","command":"getApplicableRefactors","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","startLine":126,"startOffset":17,"endLine":126,"endOffset":17}} Perf 2018 [19:51:19.352] 48::getApplicableRefactors: elapsed time (in milliseconds) 2.1181 Info 2019 [19:51:19.352] response: {"seq":0,"type":"response","command":"getApplicableRefactors","request_seq":48,"success":true,"body":[{"name":"Convert export","description":"Convert default export to named export","actions":[{"name":"Convert default export to named export","description":"Convert default export to named export","kind":"refactor.rewrite.export.named","notApplicableReason":"Could not find export statement"},{"name":"Convert named export to default export","description":"Convert named export to default export","kind":"refactor.rewrite.export.default","notApplicableReason":"Could not find export statement"}]},{"name":"Convert import","description":"Convert namespace import to named imports","actions":[{"name":"Convert namespace import to named imports","description":"Convert namespace import to named imports","kind":"refactor.rewrite.import.named","notApplicableReason":"Selection is not an import declaration."}]},{"name":"Convert import","description":"Convert named imports to namespace import","actions":[{"name":"Convert named imports to namespace import","description":"Convert named imports to namespace import","kind":"refactor.rewrite.import.namespace","notApplicableReason":"Selection is not an import declaration."}]},{"name":"Extract Symbol","description":"Extract function","actions":[{"name":"Extract Function","description":"Extract function","kind":"refactor.extract.function","notApplicableReason":"Cannot extract empty range."}]},{"name":"Extract Symbol","description":"Extract constant","actions":[{"name":"Extract Constant","description":"Extract constant","kind":"refactor.extract.constant","notApplicableReason":"Cannot extract empty range."}]},{"name":"Extract type","description":"Extract type","actions":[{"name":"Extract to typedef","description":"Extract to typedef","kind":"refactor.extract.typedef","notApplicableReason":"Selection is not a valid type node"},{"name":"Extract to type alias","description":"Extract to type alias","kind":"refactor.extract.type","notApplicableReason":"Selection is not a valid type node"},{"name":"Extract to interface","description":"Extract to interface","kind":"refactor.extract.interface","notApplicableReason":"Selection is not a valid type node"}]},{"name":"Generate 'get' and 'set' accessors","description":"Generate 'get' and 'set' accessors","actions":[{"name":"Generate 'get' and 'set' accessors","description":"Generate 'get' and 'set' accessors","kind":"refactor.rewrite.property.generateAccessors","notApplicableReason":"Could not find property for which to generate accessor"}]},{"name":"Move to a new file","description":"Move to a new file","actions":[{"name":"Move to a new file","description":"Move to a new file","kind":"refactor.move.newFile","notApplicableReason":"Selection is not a valid statement or statements"}]},{"name":"Convert to template string","description":"Convert to template string","actions":[{"name":"Convert to template string","description":"Convert to template string","kind":"refactor.rewrite.string","notApplicableReason":"Can only convert string concatenation"}]},{"name":"Infer function return type","description":"Infer function return type","actions":[{"name":"Infer function return type","description":"Infer function return type","kind":"refactor.rewrite.function.returnType","notApplicableReason":"Return type must be inferred from a function"}]}]} Info 2020 [19:51:19.353] request: {"seq":50,"type":"request","command":"quickinfo","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","line":129,"offset":16}} Perf 2021 [19:51:19.364] 50::quickinfo: elapsed time (in milliseconds) 11.1055 Info 2022 [19:51:19.364] response: {"seq":0,"type":"response","command":"quickinfo","request_seq":50,"success":true,"body":{"kind":"alias","kindModifiers":"declare","start":{"line":129,"offset":12},"end":{"line":129,"offset":22},"displayString":"(alias) const Controller: <TFieldValues extends FieldValues = FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>(props: ControllerProps<TFieldValues, TName>) => import(\"react\").ReactElement<any, string | import(\"react\").JSXElementConstructor<any>>\nimport Controller","documentation":[],"tags":[]}} Info 2023 [19:51:19.364] request: {"seq":51,"type":"request","command":"geterr","arguments":{"delay":0,"files":["/Users/aleksei.tsikov/git/project/src/Component.tsx"]}} Perf 2024 [19:51:19.364] 51::geterr: async elapsed time (in milliseconds) 0.4231 Info 2025 [19:51:19.366] event: {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","diagnostics":[]}} Info 2026 [19:51:19.825] event: {"seq":0,"type":"event","event":"requestCompleted","body":{"request_seq":51}} Info 2027 [19:51:19.827] request: {"seq":52,"type":"request","command":"quickinfo","arguments":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","line":129,"offset":16}} Perf 2028 [19:51:19.839] 52::quickinfo: elapsed time (in milliseconds) 11.8457 Info 2029 [19:51:19.839] response: {"seq":0,"type":"response","command":"quickinfo","request_seq":52,"success":true,"body":{"kind":"alias","kindModifiers":"declare","start":{"line":129,"offset":12},"end":{"line":129,"offset":22},"displayString":"(alias) const Controller: <TFieldValues extends FieldValues = FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>(props: ControllerProps<TFieldValues, TName>) => import(\"react\").ReactElement<any, string | import(\"react\").JSXElementConstructor<any>>\nimport Controller","documentation":[],"tags":[]}} Info 2030 [19:51:19.839] request: {"seq":53,"type":"request","command":"geterr","arguments":{"delay":0,"files":["/Users/aleksei.tsikov/git/project/src/Component.tsx"]}} Perf 2031 [19:51:19.840] 53::geterr: async elapsed time (in milliseconds) 0.1562 Info 2032 [19:51:19.841] event: {"seq":0,"type":"event","event":"syntaxDiag","body":{"file":"/Users/aleksei.tsikov/git/project/src/Component.tsx","diagnostics":[]}}
...
Here's the minimal repro (basically, only
react
andreact-hook-form
) https://github.com/atsikov/ts-4.5.2-perf-issueI've found out that this issue is reproducible with
react-hook-form < 7.17.2
. In react-hook-form/react-hook-form@85097ae types were improved, so with>= 7.17.2
type hints and autocomplete work as expected.
...
4.5.2
created 30 times more (intermediate?) types and consumed 8 times more memory.TS 4.4.4 extended diagnostics
Files: 50 Lines of Library: 26160 Lines of Definitions: 24762 Lines of TypeScript: 14 Lines of JavaScript: 0 Lines of JSON: 0 Lines of Other: 0 Nodes of Library: 112958 Nodes of Definitions: 60457 Nodes of TypeScript: 55 Nodes of JavaScript: 0 Nodes of JSON: 0 Nodes of Other: 0 Identifiers: 58865 Symbols: 39464 Types: 28967 Instantiations: 86282 Memory used: 93470K Assignability cache size: 17107 Identity cache size: 62 Subtype cache size: 0 Strict subtype cache size: 0 I/O Read time: 0.01s Parse time: 0.48s ResolveModule time: 0.02s ResolveTypeReference time: 0.00s Program time: 0.53s Bind time: 0.21s Check time: 0.64s printTime time: 0.00s Emit time: 0.00s Total time: 1.39s
TS 4.5.2 extended diagnostics
Files: 50 Lines of Library: 25009 Lines of Definitions: 24762 Lines of TypeScript: 14 Lines of JavaScript: 0 Lines of JSON: 0 Lines of Other: 0 Nodes of Library: 112478 Nodes of Definitions: 60453 Nodes of TypeScript: 55 Nodes of JavaScript: 0 Nodes of JSON: 0 Nodes of Other: 0 Identifiers: 58582 Symbols: 39008 Types: 1048793 Instantiations: 135356 Memory used: 724704K Assignability cache size: 7007111 Identity cache size: 27 Subtype cache size: 0 Strict subtype cache size: 0 I/O Read time: 0.03s Parse time: 0.49s ResolveModule time: 0.02s ResolveTypeReference time: 0.00s Program time: 0.57s Bind time: 0.22s Check time: 93.30s printTime time: 0.00s Emit time: 0.00s Total time: 94.09s
Originally posted by @atsikov in #46735 (comment)