-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Dart LSP slow startup/first response on large codebase #52947
Comments
Do you mean it takes the same time (~30s) for both If you start the server with |
Got a log now and the first thing I see is the initial request starts at
This one was 3 seconds (does it really need to analyze the xml files?)
Another one that took a couple of seconds
In the end I can see the following which is also >10 sec (note that above is a similar line but that happened in the middle of the log)
|
Sorry, it's still not clear to me whether
The time prior to the first One thing that would probably speed things up at the expensive of only analyzing a subset of projects is setting |
I would say it roughly matches the time of
This matches the project's folder path (copy pasted and removing the project name:
I can already see (and did this to try and speed things up) that I am using
I also noticed that after this initial LSP analyzing and the first LSP action takes place I would expect all the subsequent requests to be fast, but I find that sometimes the 2nd and 3rd requests are also slow (not 30 sec slow but more around 10 sec slow), might be another topic though but wanted to bring it up anyway :) |
Thanks for the clarification. It sounds like the issue is just that initial analysis takes longer than you'd expect. Without a concrete project to test with, it's hard to say whether the times you're seeing are normal or not. I'm surprised that On the left here I had an open workspace with 6 projects, then when I enabled If your workspace has a large number of projects and you're not opening files from many of them, I would expect this to make a noticeable difference. |
@DanTup I did the same and is stating here was also another look at the timings (learned something new) |
What files did you have open? You shouldn't see lots of contexts when using For example, if I open the Can you confirm whether you're seeing 14 contexts with no/one open file, or if you had many files open? If you had zero/one files open, are you able to verify in the log that Thanks! |
@RobertBrunhage @DanTup I have the same issue where I work. We have around 2.3k files and the analyze and lsp is super slow. I do not have any statistics but if requested I could get some if you want some more data to look at? |
@joeldegerman99 it would be interesting to know:
|
@DanTup I have a pretty large Flutter project. It takes ~30 seconds (as seen in the timings) to actually start writing Dart with an active LSP. I only have 1 context, and I use whatever the default is for Also is it a known issue that the "Analyzer Additional Args" setting doesn't get applied when the Reload Window command is triggered? |
@Reprevise 30s does sound pretty slow to me - does this reproduce after a restart (eg. with no code changes or SDK change)? For comparison, when I open my analysis server workspace, I see:
Can you reproduce this on a public project? An instrumentation log may help, but it can contain parts of your source files so is best collected with a public project.
Nope, it's definitely not :) That command actually tears down the whole extension host and restarts it, so it's not clear to me how Reload Window would behave differently to something like just restarting VS Code. If you enable the analysis server log it should record exactly what arguments it's starting the server with. If you think it's not working right, please file an issue at https://github.com/Dart-Code/Dart-Code/issues/new/choose with details. Thanks! |
I cannot, I tried it with the flutter project and the LSP was pretty speedy, even though its lib folder takes up 3x more space than ours. Perhaps it has something to do with the number of dependencies we use? We have 76 normal dependencies, and 11 dev dependencies. |
@Reprevise if you copy your list of dependencies/dev_dependencies into a new project (and add imports for them), does it repro? |
@DanTup We have 5 private packages, can it be a performance bottleneck and about the same amount of dependencies as @Reprevise ? I will fix something for you to look at tomorrow or start of next week. |
Do the imports have to be used? |
@joeldegerman99 I wouldn't expect private packages to be any different to public packages. Are they just @Reprevise I'm not certain, but I don't think so - I think the analyzer just needs to "discover" the files to load them. However if it seems to not work let me know and I'll do some testing. Some other numbers that could be useful to know.. if you run the Dart: Open Analyzer Diagnostics from VS Code and then click on the "Contexts" page, for each context under "Context Files" there will be a count of "added files" and "implicit files". Those counts may be useful (for each context) to get an idea of how many files there are including dependencies. |
Something else to add is that I've been iterating on this same Flutter project for a few years now. I thought I'd try cloning it from the source repository and the LSP is pretty damn fast now. The clone from the source repository has 1 less "added files" (688) and 5 less "implicit files" (3517) and it starts in 5 seconds compared to ~25 seconds on the "old" project. |
@Reprevise that's odd - are there any differences in things that might not be in the source folder (for example VS Code settings that might be gitignored) that could be different between them? |
Yeah I think the issue was the |
Hmm, that's interesting to know - it's probably too late now if you've already cleaned it, but it'd be interesting to know why it got so big. @joeldegerman99 it might be interesting for you to try the same - rename the |
@Reprevise out of interest, does your project have any code-gen? If you run your app a few times (maybe making some trivial changes) , do any files start building up in that directory? |
Yes, our project uses code-gen pretty heavily. On the first run of build_runner, the .dart_tool folder went from 89.1 MB (I did run the app after running |
@Reprevise thanks, I'll do some testing! |
@Reprevise I did some testing with the Freezed example, and although the If it does keep growing for you, please let me know the steps. |
@Reprevise @joeldegerman99 also - could you confirm which OSes you're on? We have some thoughts about the time spent setting up watchers, and the watcher implementations are platform-specific. Thanks! |
I'm on Windows 11. I'll get back to you on your previous comment tonight. |
I'm seeing 15s long initialization times w/o any analyzer plugins. I had Still though, taking out my ~5.8GB build folder and ~500MB .dart_tool folder made it so much faster (~4 seconds instead of ~15). |
Are you able to capture an instrumentation log with the plugin enabled? It adding 30s sounds suspicious, but the fix for that should've been included in 3.22. What's the timing (without plugins) if you take out only the |
Having the bloated With regards to deleting vs excluding the build folder, deleting the folder feels slightly faster than excluding it though I have no solid evidence to back that up. |
@Reprevise thanks! Looking at the log you sent me, it appears that the server started at 15:49:04.926 (GMT) and the first analysis ended at 15:49:21.133 which looks like around 15 seconds (and the initialization appears to complete very quickly). I can also see the plugin generating diagnostics from 15:49:37.494 to 15:49:48.198 which is approx 11 seconds. What is it you're measuring when you're seeing 45s? (as far as I can tell, you're not hitting the 30s issue I noted should've been fixed in this version).
If you're able to capture a log of each of these (without the plugin) I'd be interested in comparing them. I hoped there would be no difference, but I don't know if excluding prevents us walking the folder entirely. |
@DanTup I'm going to send you another log but it'll be unrelated to your request about the About the long startup time, would it be correct to measure the time between the first entry in the log, and the entry right before the first publishDiagnostics? |
That does sound odd - it's probably worth filing a specific issue about that with details (and I'll review the log you send). If you can include approx timestamps of when you first opened the project, went away, and came back, that may be useful too.
When trying to understand if something is a startup/initial analysis issue, I'll look for when this appears in the log:
This is when the server believes it has completed analysis. However, the specifics of what is startup/initial analysis is probably not so important here if something appears to be taking much longer when you open a project. If it seems to you that something at startup is taking ~45s then I'm interested in understanding what that might be (but that requires understanding what you're seeing to reach that conclusion - what are you seeing/measuring?). |
@DanTup I've opened a new issue and included the line in the log when I believe I came back. To summarize (because there are so many comments here):
This slow startup time (~15s) is my main concern here, I personally don't really care about the ~30s of |
Can you confirm what you're measuring for this? Do you mean it takes an extra 30s for custom_lint to report its own errors, or something else? (I know it's not your priority, but if plugins are causing any non-plugin functionality from the server to be delayed by anything like 30s, I would like to understand what's happening there). Will think about how we might be able to handle |
Sure, so what I mean is that the LSP starts up, and reports the 18 diagnostics in my project, and autocomplete and the rest of the LSP features come online. Then, |
The Could you also confirm the exact version of Thanks! |
I have emailed you a clean instr log of the analyzer, w/o me opening any files. The versions are as follows:
To be clear, the Dart LSP is perfectly usable (with autocomplete, etc) while custom_lint is doing it's own analysis so that 30s I'm waiting I can still write code using the full features of the LSP. |
@Reprevise sorry for the delay - I just looked at this but you didn't include a copy of the timing page showing exactly how long the initialized event was recorded as. Could you capture a log file and include a matching screenshot showing the exact timing recording for the initialized event when the plugin is enabled (but, without the large build folder). (I could understand the large build folder making |
@DanTup I have emailed you the logs and the screenshot of the timings page. The log is w/o the large build folder but does have Incase you can't see the screenshot in the email, here it is: |
Hi, I'm using vscode on a small/medium sized flutter app. The dart language server takes about half an hour to one hour before it can offer any completion or type information to the IDE. While I'm waiting for it to start working, it uses about 65% of 1 CPU core (when I have 4 cores / 8 threads) and basically does almost no IOs. Since an hour is a long time to wait every time I launch vscode, I tried many things to understand what it is doing and why it's not even 100%ing my CPU or my SSD.
Finally, I found a lead with So it seems that it is scanning my whole OS, which is huge, and doing so very slowly to avoid saturating the CPU or the SSD. Looking more at the opened file descriptors, I see that the So I'm trying to exclude
EDIT: the language server also takes about 11GB of resident memory which also seems very excessive. |
@PaulGrandperrin could you file a specific issue for the problem you're seeing (that is, excluded folders are still enumerated during startup) and CC me? |
Do you, by any chance, have any symbolic links under your project directory? The analyzer will blindly follow symbolic links while trying to figure out what files are part of your project. But it doesn't (normally) look at anything outside the project directory, except that it will walk up the parent directories if it hasn't found either an analysis options file or a (I'm assuming that by "project directory" you mean the directory you opened in the IDE.) |
@DanTup Ok I'll do that when I go back to this problem and investigate a little more. @bwilkerson Yes, the way So my guess is that Dart follows those symlinks, which makes sense. I'll investigate a little more to try to understand better how things unfold. Is there a way to make the language server extra extra verbose and record everything it does in a file? |
One important thing is that, dart, my flutter sdk and all my dev env comes from this This might also explain why the language server ignore the exclusion, because its SDK files are in there. @DanTup
@bwilkerson Yes, that's what I meant I'll try to give you more info later, thanks for your replies. |
I'm not sure there won't be issues by having your SDK inside an ignored folder, but I'm surprised that we walk all of that folder if it's excluded (in a quick test, I couldn't repro the server trying to ready anything nested inside a folder excluded with |
@DanTup I spent a few more hours trying to understand this issue and here's what I found so far: My project also uses rust and actually I understood something about my project's file tree is making the bug appear or disappear.
When I open the project with vscode at the
But if I open with vscode the subproject So I think I'm going to give up here, and just have multiple IDEs open at the same time, with the flutter/dart extensions only enabled for the flutter sub project. |
My bad, actually, I really don't know why, and I now need to do other things.. |
@PaulGrandperrin are you able to reproduce this in an isolated example (eg. by creating a new project and putting a symlink inside it to somewhere further up the tree)? I wasn't able to repro the behaviour you see last time I tested, so having instructions to produce a project that triggers it would really help. Thanks! |
All of the attempts you posted above appear to be VC Code settings. Curious to know whether you've attempted to use an analysis options file to disable analysis of everything under
Excluding files and directories in the analysis options file doesn't prevent the analyzer from looking in them when there's a direct import that it needs to follow, it just prevents it from traversing those directories to find files to analyze. It should be fine to exclude them. |
Dart SDK version: 3.0.6 (stable) (Tue Jul 11 18:49:07 2023 +0000) on "macos_arm64"
LSP takes a long time before LSP actions work
Not sure how to debug this so if you have tips/approaches, please let me know!
In short, when I open a project with Neovim the dartls LSP starts and in a large project takes towards half a minute for anything related to the LSP to work (hover docs, code completion, code actions etc).
Below I added duration for
dart analyze
withtime dart analyze
with a small project and large project to see the difference. Not sure if this command is even helpful in debugging but at least it shows the difference I experience.Small project
Large project
The large project contains, internal packages and is in general very large (>690k LOC counted with
find . -name '*.dart' | xargs wc -l
), but I would still expect it to be faster than 30 seconds for anything to work, and the subsequent action takes ~half the time of that (18 seconds). After those two (first 30 sec wait for a LSP action, and then 18 sec, it becomes almost instant).Again, if there are better ways to debug this, please let me know.
I will add this here as well as that is where I got the config from (mine is a bit leaner as I don't use
outline
etc.https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/server_configurations/dartls.lua
Tweet referencing this issue -> https://twitter.com/RobertBrunhage/status/1680840204309913600
The text was updated successfully, but these errors were encountered: