-
-
Notifications
You must be signed in to change notification settings - Fork 206
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
"getCompletion" from TypeScript LSP scans the entire project for each file. #2329
Comments
This is most likely because of the icon library you're using. Some icon libraries bloat the project dependencies with a ton of files that take a long time to process. This icon library seems to be a private package so we can't investigate what exactly the bottleneck is. I guess it might be something similar to #2244 (comment). It might not have the big export map issue. However, the parser error stage issue might still apply.
No. We don't create a TypeScript language service for every file. But TypesScript will need to check if the cache is still usable in the new file since some relative path might change. Some auto import in the cache might be inaccessible in the new file. But it is still strange for it to take this long. We still need a reproduction to check why the cache in missing or why the cache got invalidated. |
This is our private UI kit. It contains around 2500 icons. I even had to write a plugin for esbuild and vite to optimize imports from the index.js file, which re-exports these icons. I can try to create a simulation of our project where we could reproduce this issue. Is it possible not to preprocess the Svelte component for import completions? Maybe introduce some flag that would skip this process, which could speed up this process. Then we would lose component typings, right? Or maybe for import completions, it's enough to assume that the default export is always exported from there, and that's it, and then preprocess the component when using it to get typings. |
I also decided to check if the cache is lost when I try to import Svelte components in different TypeScript files, and it doesn't happen. The cache remains, and getCompletion works quickly. |
We can't tell if it's a problem with our implementation unless there's a reproduction. I tried multiple icon libraries but didn't reproduce the problem with switching files. The export info map is cleared when switching files but there are still other caches so it's not completely restart. In the meanwhile, You can probably try to exclude the icon library from auto-import with the javascript.preferences.autoImportFileExcludePatterns or typescript.preferences.autoImportFileExcludePatterns config. |
OK, I'll try reproduce |
@jasonlyu123 Hello. Here is the repository where you can verify that the cache is not reused between files. https://github.com/MrWaip/svelte-lsp-slow-complitions You can open the file |
I continue exploring LSP. Your suggestion to exclude icons in The project I'm talking about was small.
I decided to add this setting to a larger project. It didn't help for some reason. I disabled all extensions. Turned off almost all features of Svelte LSP. Enabled debug mode and trace in the settings of the Svelte extension. Here's the trace:
|
Without cache, the response time for completion requests was 43 seconds in a large project.
|
Ok. This is the same issue as #2244 (comment). The issue is because of the giant export map. TypeScript loops through the export map to find the subpath for each symbol so it's an Is there a reason why you need an export map of this size? This probably needs to be optimised in upstream TypeScript. However, I am hesitant to open an issue because the export map is unusually big. |
Is there any way to improve retrieving completions from an erroneous location? After all, I'm just trying to select a component, and I definitely don't expect it to lead to scanning the entire project. |
It's a limitation we have, see #776. We could probably add a |
I cleaned up exports in package.json. I closed the tag so that the parser wouldn't complain. I excluded a directory with a large number of files in the settings. In my large project, this took 30 seconds. It's still strange. 81f5a7e7-5439-4883-a1ba-ff56b9fd83cf.mp4 |
What's the point of this? Projects often have many components. Typically, you don't remember their names, especially if the project has been around for a while. In my example, I want to import an icon (or anything else). I type in the first few characters I remember and want to see suggestions, then use them as a reference to remember what I'm looking for. Seems pretty standard to me. |
Over the past 3 years, our project has become very large. And perhaps what irritates our entire team the most is that it has become difficult to work in any IDE. Any of them. Svelte LSP in VS Code consumes all the RAM. In Neovim, everything just hangs, you can forget about Svelte LSP altogether. In WebStorm, it's better, but auto-import doesn't work at all. And that's our main pain point. |
We're already joking (or almost seriously) with each other that it's time to rewrite all of this in Go or Rust. |
By the way, in the latest video, it's noticeable that after the completion request, nothing happens, there's some waiting. It's unclear what's going on. And then after some time, traces and other logs appear. Any theories? I've already turned everything off, no ideas. UPDATE: I deleted node_modules, but the completion request still took more than 30 seconds. By process of elimination, I began deleting directories from the project and noticed that textDocument/completion started to work faster. I understand that, initially, when I try to go to definition, or hover, or request completions, the project scanning starts. And only after that does the actual request execute. We have 10k files in our project, according to Git. If all these components are still being preprocessed, it's sad. |
What I meant is that 12000+ lines of package.json isn't normal. The reason it is slow is because TypeScript loops through the export map for subpath export for each symbol found. If there are 2 exports per file and there are 2000 conditions in your export map. There'll be 2* 2000 * 2000 loops. This needs to be optimised in TypeScript but I currently only see this in svelte icon libraries so I think it would be better to know why this is needed in the first place and solve that problem. Even if it's reported in TypeScript, they might still ask why can't just use the
The |
I got you. I'll definitely try to optimize the export map of icons. |
Maybe we'll add everything that isn't used during development to the exclude list but include it in the pipeline. |
@jasonlyu123 Are there any other optimizations possible? But thank you anyway! |
Damn. It's not supported( |
Did you mean "used to load different tsconfig that doesn't use the name 'tsconfig.json'" or "Build-Free Editing with Project References"? The latter won't help with start-up time since the source file is still loaded. |
I mean that |
are there any progress made on this? I am too experiencing super laggy experience on a larger sveltekit codebase. The experience seems to degrade overtime, sometimes even crashing. i have to restart vscode to get it to be usable |
@noobmaster19 "degrade overtime" is most likely unrelated to this issue. Please try reading through other issues on common problems that need user action. The most common one is your tsconfig.json/jsonconfig includes build output. If none of the existing issues match your problem, please open a separate issue with reproduction and instructions. If it's not possible, at least provide a CPU profile, memory snapshot, tsconfig.json and package.json. You can record a CPU profile following these steps: #1984 (comment). For memory snapshot, follow the CPU profile instructions but it's in the memory tabs instead of the performance tabs |
Describe the bug
Issue: A request for completions from the editor in my working project takes 10 seconds. I decided to investigate why. Every subsequent request for completions from the same Svelte document is instantaneous. However, as soon as I open another Svelte component, I have to wait another 10 seconds.
I deployed language tools locally and configured them for my working project. Then I started measuring where the bottleneck was. That's how I ended up in CompletionProvider (packages/language-server/src/plugins/typescript/features/CompletionProvider.ts). And the slow call turned out to be the one where we access TypeScript (
const response = lang.getCompletionsAtPosition()
).I delved even deeper and realized that the slowest request for completions in the TypeScript LSP is
function getGlobalCompletions()
.This function attempts to suggest completions for imports, and this takes the entire 10 seconds (collectAutoImports -> exportInfo.search()). TypeScript caches this result, but if I open another file, it starts over. This is very strange. Are you creating a TypeScript LSP for every Svelte file? In my project, the TypeScript LSP scans an array of 23,580 elements for every completion request. And I suppose it also transforms Svelte files internally to understand what can be imported from there. This is a huge amount of cache for every file.
Reproduction
I don't know. Just ask for completions
Expected behaviour
I would like the completion request to be executed faster and not to be repeated when opening another Svelte document.
System Info
Which package is the issue about?
No response
Additional Information, eg. Screenshots
1e907842-3376-4479-862f-84b6deb1fbbf.mp4
The text was updated successfully, but these errors were encountered: