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

Dart Analyzer very slow/stuck #55281

Open
JonasJW opened this issue Mar 22, 2024 · 182 comments
Open

Dart Analyzer very slow/stuck #55281

JonasJW opened this issue Mar 22, 2024 · 182 comments
Labels
analyzer-stability area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-performance Performance/memory issues in analyzer/cfe P2 A bug or feature request we're likely to work on type-performance Issue relates to performance or code size

Comments

@JonasJW
Copy link

JonasJW commented Mar 22, 2024

Dart & Flutter has suddenly become unusable slow in VSCode. Intellisense won't load within 30+ seconds, syntax highlighting won't update, jumping to code definitions loads infinitely, etc.

This seems to be especially the case on bigger projects, on a newly created project it works fine. I tried switching to Android Studio which seems to behave similarly (maybe a little better).

I tried uninstalling all extensions, even completely removing VSCode with any data stored and reinstalling it. As soon as I install the Dart extension, it is unusable. I also tried setting the following settings:

"dart.previewLsp": true,
"dart.useLegacyAnalyzerProtocol": true,
"dart.useLsp": false,
"dart.autoImportCompletions": false,

I'm on macOS 14.4, VSCode Version 1.87.2 (Universal),

In the Activity Monitor, there is the dart:analysis_server.dart.snapshot process running with around 1 GB of used memory. I'm not sure if this is normal.

Here is a screenshot from the Dart Analyzer (which I'm also having trouble opening)

Screenshot 2024-03-22 at 20 47 42

dart info output:

General info

  • Dart 3.3.2 (stable) (Tue Mar 19 20:44:48 2024 +0000) on "macos_arm64"
  • on macos / Version 14.4 (Build 23E214)

Project info

  • sdk constraint: '>=2.17.0 <3.0.0'

Process info

Memory CPU Elapsed time Command line
6 MB 0.0% 11:53 dart devtools --machine --allow-embedding
393 MB 100.6% 11:53 dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.85.20240318
29 MB 0.0% 11:53 flutter_tools.snapshot daemon
35 MB 0.1% 00:23 flutter_tools.snapshot debug_adapter
121 MB 10.8% 00:23 flutter_tools.snapshot run --machine --start-paused -d B95DD896-131D-4163-A83C-1AC8A70E8560 --devtools-server-address http:/ --target /main.dart --web-renderer canvaskit --web-port 5000

Any recommendations on how I could possible fix this would be very welcome!

@JonasJW JonasJW changed the title Dart Dart Analyzer very slow/stuck Mar 22, 2024
@lrhn lrhn added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Mar 24, 2024
@keertip keertip added type-performance Issue relates to performance or code size P1 A high priority bug; for example, a single project is unusable or has many test failures labels Mar 26, 2024
@keertip
Copy link
Contributor

keertip commented Mar 26, 2024

@DanTup , do you see this? Have there been more reports of this kind?

@keertip
Copy link
Contributor

keertip commented Mar 26, 2024

/ cc @bwilkerson

@DanTup
Copy link
Collaborator

DanTup commented Mar 26, 2024

I've not seen any other reports like this. 100% CPU certainly does not look healthy if it's persisting for a long period after initial analysis.

@JonasJW a few questions:

  • How big is the open workspace (code --status I think should give a summary of the number of each file type)
  • Might it contain any symlinks (that could result in analyzing more than just this folder, or even cycles?)
  • You noted that this issue started recently - are there any things that you updated around the time it started (VS Code, the VS Code extensions, the Dart/Flutter SDKs)?
  • Are you able to get a screenshot of the servers Timing page (the one you gave above was the Completion page) which will include timings for a larger set of requests

@MaximeRougieux
Copy link

We were having the same issue and using the custom_lint package (v0.5.7).

Removing it completely seems to have solved the issue for us, are you using it too, and can you try to remove it to confirm it comes from there if you are ?

@keertip
Copy link
Contributor

keertip commented Mar 27, 2024

/cc @scheglov

@keertip keertip added P2 A bug or feature request we're likely to work on and removed P1 A high priority bug; for example, a single project is unusable or has many test failures labels Mar 27, 2024
@JonasJW
Copy link
Author

JonasJW commented Mar 29, 2024

@DanTup Thanks for the response and sorry for the late reply.

code --status output:

Version:          Code 1.87.2 (863d2581ecda6849923a2118d93a088b0745d9d6, 2024-03-08T15:21:31.043Z)
OS Version:       Darwin arm64 23.4.0
CPUs:             Apple M1 Pro (8 x 24)
Memory (System):  16.00GB (0.06GB free)
Load (avg):       5, 5, 6
VM:               0%
Screen Reader:    no
Process Argv:     --crash-reporter-id 0c0cb32f-913b-418e-b987-7370929419d6
GPU Status:       2d_canvas:                              enabled
                  canvas_oop_rasterization:               enabled_on
                  direct_rendering_display_compositor:    disabled_off_ok
                  gpu_compositing:                        enabled
                  multiple_raster_threads:                enabled_on
                  opengl:                                 enabled_on
                  rasterization:                          enabled
                  raw_draw:                               disabled_off_ok
                  skia_graphite:                          disabled_off
                  video_decode:                           enabled
                  video_encode:                           enabled
                  webgl:                                  enabled
                  webgl2:                                 enabled
                  webgpu:                                 enabled

CPU %   Mem MB     PID  Process
    0      115   38907  code main
    7       66   38910     gpu-process
    0       16   38911     utility-network-service
    0       33   38923  shared-process
    0       33   82195  ptyHost
    0        0   83841       /bin/zsh -il
    0        0   90120         bash /usr/local/bin/code --status
    9       66   90129           electron-nodejs (cli.js )
    5      246   83837  window [5] (auto_router.gr.dart — exercisable_flutter)
    0       98   83839  extensionHost [5]
    0       33   83879       electron-nodejs (config.js )
    0        0   83961         /usr/bin/script -t 0 /dev/null /usr/bin/arch -arm64e xcrun xcdevice observe --usb
    0       16   83962           /Applications/Xcode.app/Contents/Developer/usr/bin/xcdevice observe --usb
    0        0   83963         /usr/bin/script -t 0 /dev/null /usr/bin/arch -arm64e xcrun xcdevice observe --wifi
    0       16   83964           /Applications/Xcode.app/Contents/Developer/usr/bin/xcdevice observe --wifi
    0      426   83884       /Users/jonas/Documents/flutter/bin/cache/dart-sdk/bin/dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.85.20240327
    0        0   83886       /Users/jonas/Documents/flutter/bin/cache/dart-sdk/bin/dart devtools --machine --allow-embedding
    0       33   89935       electron-nodejs (config.js )
    0       33   89961         electron-nodejs (config.js )
  170     1081   90000           electron-nodejs (config.js )
    0       33   83840  fileWatcher [5]

Workspace Stats: 
|  Window (auto_router.gr.dart — exercisable_flutter)
|    Folder (exercisable_flutter): more than 20346 files
|      File types: transitive_digest(3856) json(1582) png(1354) flat(1004)
|                  jar(976) xml(843) webp(646) ttf(344) stamp(334)
|                  len(275)
|      Conf files: launch.json(1)
|      Launch Configs: dart(13)

To be honest, I'm not quite sure what you mean by your question about symlinks or how I can find out.

Yes, this issue seems to have started just recently without making any noticeable changes such as updating SDKs, installing extensions, etc.

Here are further screenshots, I hope this is the server timing page you meant.

Screenshot 2024-03-29 at 09 58 32

Screenshot 2024-03-29 at 09 59 31

If you have any recommendations what I can try to fix this issue, I'm happy to try that. As mentioned, I have already tried uninstalling Flutter/Dart, VSCode, etc. at the moment I don't know what else I could try.

@lulupointu
Copy link

For us updating custom_lint to 0.6.4 fixed the issue 🎉

@DanTup
Copy link
Collaborator

DanTup commented Mar 29, 2024

@JonasJW thanks - the page I meant was the one marked "Timing" on the left.

Can you also confirm whether you're using any analyzer plugins? A few comments above suggest custom_lint might have have issues (that may be fixed in 0.6.4).

You should be able to check for symlinks by running find . -type l -ls in your project folder.

@JonasJW
Copy link
Author

JonasJW commented Mar 29, 2024

@DanTup thanks for the clarification!

I don't use custom_linter or any analyzer plugins.

When I run find . -type l -ls I get a long list of I suppose symlinks that probably just belong the the packages I use, for example:

111156169        0 lrwxr-xr-x    1 jonas            staff                  29 Mar  8 17:37 ./build/macos/Build/Products/Debug-platform/exercisable_flutter.app/Contents/Frameworks/FirebaseCore.framework/FirebaseCore -> Versions/Current/FirebaseCore

Is that anything out of the ordinary?

Here the screenshots of the "Timing" page:

Screenshot 2024-03-29 at 19 47 54

Screenshot 2024-03-29 at 19 48 15

@DanTup
Copy link
Collaborator

DanTup commented Apr 4, 2024

When I run find . -type l -ls I get a long list of I suppose symlinks that probably just belong the the packages I use, for example:

111156169        0 lrwxr-xr-x    1 jonas            staff                  29 Mar  8 17:37 ./build/macos/Build/Products/Debug-platform/exercisable_flutter.app/Contents/Frameworks/FirebaseCore.framework/FirebaseCore -> Versions/Current/FirebaseCore

Is that anything out of the ordinary?

That one doesn't look like a problem, but are there any that point back up the tree (eg. creating cycles or including other large parts of the disk in the the path)?

It may be useful to enable the analyzer instrumentation log (this file can get very large - be sure to turn it off afterwards) and reproduce the issue, and see if there is anything in the log file that looks out of place while this happens (for example exceptions, or paths you would not expect to be analyzed with this project open being analyzed).

You mentioned this only happens on large projects - are any of them public projects that I could test with (or that sharing logs from would not include anything sensitive)?

@JonasJW
Copy link
Author

JonasJW commented May 8, 2024

Hi @DanTup,

I apologize for taking so long to respond. I still have this issue and it's really slowing down my development process.

are there any that point back up the tree (eg. creating cycles or including other large parts of the disk in the the path)?

Here are a few symlinks, some point up but it doesn't appear to me that they would create a cycle

./windows/flutter/ephemeral/.plugin_symlinks/firebase_auth -> /Users/jonas/.pub-cache/hosted/pub.dev/firebase_auth-4.19.1/

./build/macos/Build/Intermediates.noindex/EagerLinkingTBDs/Debug/just_audio.framework/just_audio.tbd -> /Users/jonas/Documents/project_name/build/macos/Build/Intermediates.noindex/EagerLinkingTBDs/Debug/just_audio.framework/Versions/A/just_audio.tbd

./macos/Pods/Headers/Public/Firebase/Firebase.h -> ../../../Firebase/CoreOnly/Sources/Firebase.h

./ios/.symlinks/plugins/path_provider_foundation -> /Users/jonas/.pub-cache/hosted/pub.dev/path_provider_foundation-2.3.1/

./build/macos/Build/Products/Debug/FirebaseSharedSwift/FirebaseSharedSwift.framework/FirebaseSharedSwift -> Versions/Current/FirebaseSharedSwift

In total there are over 550 symlinks. Does any of this sound problematic?

I also tried the analyzer instrumentation logs but I can't really find anything that appears out of place. However, this document seems to log all kinds of stuff and I'm not sure how to analyze it or what to look for.

Yes, unfortunately, this project is private and can't be shared. I could probably share the analyzer instrumentation logs privately with you, if that would help.

I recently tested this project on a windows laptop and the issue occurs as well. (Thus, I think completely reinstalling my mac won't even help fix it).

These issues don't appear on new Flutter projects. Maybe I could try to download a big public project and see if I have problems with other bigger projects as well? If not it must be something specific with my project but I'm clueless about where the issue could be.

@DanTup
Copy link
Collaborator

DanTup commented May 8, 2024

In total there are over 550 symlinks. Does any of this sound problematic?

Nothing above looks like an issue to me - the issue would be if the link points further up the tree so that walking the tree could cause endless cycles.

I also tried the analyzer instrumentation logs but I can't really find anything that appears out of place

The most useful thing would be knowing what's being logged during the periods where performance is bad. So if the bad performance is during startup, it would be the start of the logs (until the first progress event with "kind": "end"). If it's during completion, it would be what occurs between the textDocument/completion request and the corresponding response.

Yes, unfortunately, this project is private and can't be shared. I could probably share the analyzer instrumentation logs privately with you, if that would help.

I can't accept anything confidential (instrumentation logs can contain contents of opened files and paths/errors for other files in the workspace), but if you're able to reproduce this on a copy of the project with anything confidential removed (and perhaps only a single test file open), you might be able to get a log that doesn't contain anything confidential you can share.

Something I forgot to ask earlier - can you confirm whether you have this option ticked in the VS Code (User or Workspace) settings?

image

@JonasJW
Copy link
Author

JonasJW commented May 8, 2024

Understood, I will go back to the logs and look for these progress events. If I have something to share I will follow up on it here.

The Dart: Only Analyze Projets With Open Files was disabled. I'm trying to enable it to see it that improves it, I will update you on this.

@DanTup
Copy link
Collaborator

DanTup commented May 8, 2024

The Dart: Only Analyze Projets With Open Files was disabled. I'm trying to enable it to see it that improves it, I will update you on this.

FWIW, my recommendation would be to not use that setting (and I should update the text). Although it sounds better for large projects, it was really added for a fairly specific case (command line editors that would provide the current working directory - which may be the user home dir - as the workspace folder). While the server will start up faster for very large workspaces, opening and closing files from different projects will trigger re-creating the analysis roots which can trigger "initial" analysis for those projects.

It's beneficial if you're opening a folder that contains 100 projects and maybe only opening files from a handful, but if you're jumping between a large portion of the projects in the workspace, it's probably worse overall.

@mraleph
Copy link
Member

mraleph commented Oct 3, 2024

@JonasJW what is your current experience with analysis performance? Are you still experiencing this weird behavior?

@JonasJW
Copy link
Author

JonasJW commented Oct 3, 2024

@mraleph yes, I'm still experiencing performance issues

@DanTup
Copy link
Collaborator

DanTup commented Oct 3, 2024

@JonasJW are you able to reproduce this issue with any public projects? It might be easier to narrow down with an instrumentation log, but that log will contain parts of source code from the open projects.

If it only occurs with this one specific internal project, is it possible to make a copy of it and see if you can narrow down what causes it (for example if it's made up of many packages, can you remove some of them to narrow down if it's caused by a specific package/set of packages)?

Do you also know if this issue occurs when typing in any file, or just some subset? This issue could be similar to #56307 which may be caused by the number of files that need to be reanalyzed as you modify a file (see #56307 (comment) and #56307 (comment)).

@amrgetment
Copy link

amrgetment commented Oct 3, 2024

Maybe a related issue
Memory Leaks in the custom_lint library
invertase/dart_custom_lint#248

@larssn
Copy link

larssn commented Oct 30, 2024

We have a pretty large project (internal, 200k lines), and this issue is pretty hard on productivity.

The worst of it comes from typing new class properties. The analyzer will get stuck on these for up to 20-30 seconds.

Here's my code --status and a screenshot of top memory in Activity Monitor.

Version:          Code 1.95.0 (912bb683695358a54ae0c670461738984cbb5b95, 2024-10-28T20:16:24.561Z)
OS Version:       Darwin arm64 24.0.0
CPUs:             Apple M1 Max (10 x 2400)
Memory (System):  32.00GB (0.28GB free)
Load (avg):       4, 5, 6
VM:               0%
Screen Reader:    no
Process Argv:     --crash-reporter-id 4e581022-c36a-4fd6-8d5e-12c2b8c113c3
GPU Status:       2d_canvas:                              enabled
                  canvas_oop_rasterization:               enabled_on
                  direct_rendering_display_compositor:    disabled_off_ok
                  gpu_compositing:                        enabled
                  multiple_raster_threads:                enabled_on
                  opengl:                                 enabled_on
                  rasterization:                          enabled
                  raw_draw:                               disabled_off_ok
                  skia_graphite:                          disabled_off
                  video_decode:                           enabled
                  video_encode:                           enabled
                  webgl:                                  enabled
                  webgl2:                                 enabled
                  webgpu:                                 enabled
                  webnn:                                  disabled_off

CPU %	Mem MB	   PID	Process
    0	   197	 47912	code main
    0	    98	 47915	   gpu-process
    0	    33	 47916	   utility-network-service
    0	   623	 47918	window [1] (sales_page.dart — tillty_pos)
    0	   492	 48349	extensionHost [1]
    1	    66	 48582	     electron-nodejs (config.js )
    0	     0	 48894	       /usr/bin/script -t 0 /dev/null /usr/bin/arch -arm64e xcrun xcdevice observe --usb
    0	    33	 48896	         /Applications/Xcode.app/Contents/Developer/usr/bin/xcdevice observe --usb
    0	     0	 48895	       /usr/bin/script -t 0 /dev/null /usr/bin/arch -arm64e xcrun xcdevice observe --wifi
    0	    33	 48897	         /Applications/Xcode.app/Contents/Developer/usr/bin/xcdevice observe --wifi
    6	  3736	 77823	       /Users/lars/Library/Android/sdk/emulator/qemu/darwin-aarch64/qemu-system-aarch64 -avd Pixel_Tablet_API_35
    1	    33	 77829	         /Users/lars/Library/Android/sdk/emulator/netsimd --host-dns=8.8.8.8,8.8.4.4
    0	    33	 48584	     /Users/lars/workspace/flutter/bin/cache/dart-sdk/bin/dart tooling-daemon --machine
    0	  1147	 48593	     /Users/lars/workspace/flutter/bin/cache/dart-sdk/bin/dart language-server --protocol=lsp --client-id=VS-Code --client-version=3.98.1
    0	    33	 48836	     electron-nodejs (languageserver.js )
    0	    33	 48880	     /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/json-language-features/server/dist/node/jsonServerMain --node-ipc --clientProcessId=48349
    0	    98	 48350	shared-process
    0	    33	 48351	fileWatcher [1]
    0	    66	 59875	ptyHost

Workspace Stats: 
|  Window (sales_page.dart — tillty_pos)
|    Folder (tillty_pos): more than 20467 files
|      File types: transitive_digest(3880) class(1518) dex(782) xml(648)
|                  h(635) len(597) grpc_back(510) json(440)
|                  jar(368) c(325)
|      Conf files: launch.json(1) tasks.json(1)
|      Launch Configs: dart(5)
image

(The top consumer seems to be the Android Emulator, which is probably fine)

Here's the Dart process (if relevant):
image

Anything else I can do to help debug this issue?

@DanTup
Copy link
Collaborator

DanTup commented Mar 10, 2025

@realth000 thanks for the file - there are a lot of slow edit.getAssists requests so I think you're seeing the same issue as is discussed in #55281 (comment) (which I think @jensjoha may be working on some improvements for). I opened a sub-issue for this problem to make it easier to follow (since this issue contains multiple different issues): #60292

@knopp thanks, I can reproduce fairly long analysis when making a single-keystroke change to that file too (not to the point of needing to restart the server, but my testing was fairly limited). I've opened a specific sub-issue for this with my timings and a CPU profile at #60293.

copybara-service bot pushed a commit that referenced this issue Mar 10, 2025
Also add benchmark where lots of hover requests are fired,
mimicking IntelliJ behavior when holding ctrl and moving the mouse over
imports.

I'm getting these results on my machine:

```
4 files / CodeType.ImportCycle:
Initial analysis: 1.249438
Completion after change: 10.143719

4 files / CodeType.ImportChain:
Initial analysis: 1.367604
Completion after change: 9.936909

4 files / CodeType.ImportExportCycle:
Initial analysis: 1.233644
Completion after change: 10.011695

4 files / CodeType.ImportExportChain:
Initial analysis: 1.226382
Completion after change: 9.875991

4 files / CodeType.ImportCycleExportChain:
Initial analysis: 1.262932
Completion after change: 9.995607
```

notice the low number of files (in the chain*) or if it even is a chain
etc doesn't appear to change anything for the time it takes to become
responsive again.

Notice that in
#55281 (comment) I
noticed that something similar happened for `edit.getFixes`, but I'm yet
to actually reproduce that.

Change-Id: Iff04124825c6ea2f759b4d048a0f2988709eaebf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413981
Commit-Queue: Jens Johansen <[email protected]>
Reviewed-by: Phil Quitslund <[email protected]>
copybara-service bot pushed a commit that referenced this issue Mar 10, 2025
TL;DR: By only responding (for real) to the newest hover request a
benchmark that used to take ~10 seconds now takes ~0.6 seconds.

Details:

In #55281 (comment)
I noticed that some of the performance issues people are seeing fom the
analyzer server stem from many requests being fired, each taking longer
the wait before the next is issued, naturally building up a longer and
loger queue before responses are made. Their it was for `edit.getFixes`,
but I'm yet to actually reproduce that. I did reproduce for hover
requests though, so here I'm debounsing those hover requests.
I'm hooking into the system that already debounces completion requests
and following the pattern used there.

On my machine, running

```
out/ReleaseX64/dart-sdk/bin/dart \
pkg/analysis_server/tool/benchmark_tools/big_chain_benchmark/legacy_many_hover_requests.dart
```

I get these numbers:

Before CL (taken from the parent CL that introduces the benchmark):

```
4 files / CodeType.ImportCycle:
Initial analysis: 1.249438
Completion after change: 10.143719

4 files / CodeType.ImportChain:
Initial analysis: 1.367604
Completion after change: 9.936909

4 files / CodeType.ImportExportCycle:
Initial analysis: 1.233644
Completion after change: 10.011695

4 files / CodeType.ImportExportChain:
Initial analysis: 1.226382
Completion after change: 9.875991

4 files / CodeType.ImportCycleExportChain:
Initial analysis: 1.262932
Completion after change: 9.995607
```

With CL:

```
4 files / CodeType.ImportCycle:
Initial analysis: 1.322501
Completion after change: 0.569768

4 files / CodeType.ImportChain:
Initial analysis: 1.347588
Completion after change: 0.635748

4 files / CodeType.ImportExportCycle:
Initial analysis: 1.492362
Completion after change: 0.575233

4 files / CodeType.ImportExportChain:
Initial analysis: 1.331619
Completion after change: 0.576199

4 files / CodeType.ImportCycleExportChain:
Initial analysis: 1.342130
Completion after change: 0.608064
```

Change-Id: Ide3dbc4dfb885af9e1c46a763338ba545c0ab7db
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413982
Reviewed-by: Phil Quitslund <[email protected]>
Commit-Queue: Jens Johansen <[email protected]>
@johnniwinther johnniwinther added the model-performance Performance/memory issues in analyzer/cfe label Mar 10, 2025
@jensjoha
Copy link
Contributor

@realth000 thank you for the data!
There are a surprising amount of "analysis.setAnalysisRoots" operations, e.g. between ~01:46:51 and ~1:55:38 (less than 9 minutes) there are 27 such requests which combined spend something like 4 minutes 22 seconds answering --- about half the timespan.
Do you have any idea what caused that?
The only way I can come up with is adding a new folder to the open "project" or something, but some of these requests are less than a second apart so I doubt that's it.

@realth000
Copy link

realth000 commented Mar 10, 2025

@jensjoha I restarted the dart analyzer server after dart run build_runner build -d because it doesn't include the generated code (this may be another topic, not in this issue), maybe the restart made things worse?

I have some git submodules in my repo, those are also dart projects.

You can clone my project here https://github.com/realth000/tsdm_client if you'd like to.

Some new info I found yesterday: the performance got much better when I disabled most configs in actions on save:

Image

Before, for the first and second config I chose "all files types" and Whole file. organize imports, rearrange code and Run code cleanup were enabled.
I think the stuck are directly caused by these IDE features.

@parnesen
Copy link

FWIW I have this issue too. I'm running Dart/Flutter/Serverpod in VS Code in Windows 11

@DanTup
Copy link
Collaborator

DanTup commented Mar 10, 2025

@parnesen please check the instructions in #55281 (comment) to collect a diagnostic report after you've reproduced the issue you're seeing.

If you can reproduce on something open source / public, then please provide details and repro steps.

@eli1stark
Copy link

eli1stark commented Mar 15, 2025

@DanTup

I have a suspicion that this is related to barrel files. This issue describes the problem very well: #50369.

I started experiencing this problem more and more as my project grew, and now I have around 300 files in my shared.dart barrel file. When I edit it for testing purposes, I experience the exact same issue with the analyzer taking 10 seconds to load, which I experience from time to time when working in my project. I tried to do experiments in isolation, no in/out dependencies, and the analyzer is fast. This comment summarizes it pretty well: #50369 (comment).

Also, I think this comment explains the issue that might be the root cause for me personally in my project: #50369 (comment)

@melWiss
Copy link

melWiss commented Mar 16, 2025

we don't have barrel files in our source code and it has the same behavior, however we have some gigantic generated files, even though they're not analyzed, I'm still thinking that it could be the source of the problem (the generated files are from the auto_route_generator and injectable_generator)

@codelovercc
Copy link

codelovercc commented Mar 17, 2025

Do we have a time-line for this issue? I want to upgrade my Flutter to 3.29, but this issue makes 3.29 unusable.

@joachimbulow
Copy link

I want to upgrade my Flutter to 3.29, but this issue makes 3.29 unusable.

^ I do not think version 3.29 is related to this issue - we are seeing this constantly for 3.22.3.

But yea, I think this should be the very top priority for the sdk team. 2 minute build_runners + analyzer getting stuck every other minute makes Dart feel like a severely handicapped language atm. At least for mid-large scale flutter development.

@davidmorgan
Copy link
Contributor

But yea, I think this should be the very top priority for the sdk team. 2 minute build_runners + analyzer getting stuck every other minute makes Dart feel like a severely handicapped language atm. At least for mid-large scale flutter development.

2 minute build_runner is a different issue, work in progress here :)

@mraleph
Copy link
Member

mraleph commented Mar 17, 2025

This issue is conflating too many things together.

First of all, I think we have two separate problems on our hands.

One problem is that some people indicate a regression in Flutter 3.29 / Dart 3.7 release. To the best of my knowledge we still don't have any clear idea of what could have caused a regression, what this regression is and what can be done to address it. I suggest that any reports and discussions about Flutter 3.29 regression go into a separate issue: #60335

The second problem is long analysis times. There are might be different reasons for it - but one of the common pattern that we see is: editing code in a library which is transitively depended upon by large amounts of code. When you edit such library you cause reanalysis of all libraries which depend on it.

Some files are naturally like this1, but there are there are several other ways to get your code base into such state. Common case is barrel files, where you create a file which imports large amount of libraries and then re-exports them all. However barrel files are just a special case of this problem. Routing is another case (I suspect that's what @melWiss hits): one of the common ways to structure routing means you end up creating a library which contains definitions of your routes - and this library both imports (directly or transitively) most of the libraries that define UI of your app and at the same time is imported into large number of libraries which define the UI. This means whenever you edit one library which is imported by the library which defines routes - you cause invalidation and reanalysis of all libraries which in turn import the library which defines route.

The problem with such dependency graphs is that the coarse invalidation strategy employed by the analyser does not scale for them. @scheglov is working on addressing this, but we don't have fully concrete timeline for fine grained invalidation landing in the analyzer.

So the best you can do today is to try and identify if your project falls into this trap and try to restructure dependencies between your files in a way that avoids it (e.g. move away from barrel files, rewrite your routing in a way that avoids cyclic dependency between god file defining routes and libraries which define UI).

@jensjoha have written a tool which tries to analyze the code base and extract strongly connected components from it. You can try running it on your code base to get insights. Example of running it:

$ dart pub global activate -sgit https://github.com/jensjoha/dependency_insight/
$ dart pub global run dependency_insight:dependency_graph $PWD/lib

Footnotes

  1. e.g. if you edit widget/binding.dart in Flutter framework you naturally need to reanalyze almost everything because this library defines core classes used by everything else.

@amrgetment
Copy link

amrgetment commented Mar 17, 2025

@jensjoha can you make the project sdk: ^3.6.0 or remove the dart restriction? I got the following error

Because pub global activate depends on dependency_insight from git which
  requires SDK version ^3.7.0, version solving failed.

I don't use barrel files a lot so I think it is not a barrel files issue

Image

but I have part of for blocs

Image

And I have freezed, json serialization and auto route

@bwilkerson
Copy link
Member

@melWiss

... we have some gigantic generated files, even though they're not analyzed ...

By "not analyzed" do you mean that they are "excluded" from analysis in the analysis options file?

@amrgetment
Copy link

amrgetment commented Mar 17, 2025

I have all generated files excluded but the same issue

analyzer:
  exclude:
    - build/** # Exclude generated files in the build directory
    - .dart_tool/** # Exclude Dart tool-generated files
    - gen/** # Exclude other generated code, if any
    - lib/**.g.dart
    - lib/**.gr.dart
    - lib/**.freezed.dart

Note: I have auto fix 😁 , auto save 😳 and auto format 😂 in my vscode

  "files.autoSave": "afterDelay",
  "files.autoSaveDelay": 1000,
  "editor.formatOnSave": true,
  "editor.foldingImportsByDefault": false,
  "editor.codeActionsOnSave": {
    "source.organizeImports": "explicit",
    "source.fixAll": "always"
  },

@scheglov
Copy link
Contributor

Are these **.g.dart files parts or libraries? If they are parts, we still analyze them. Excluding a file means that it is not a "start" of analysis, but if a library references such excluded file, e.g. because it is a part (then we resolve the AST), or imported into another library (then we only build its element model), the file is still processed.

@bwilkerson
Copy link
Member

I have all generated files excluded ...

In retrospect the name of the "exclude" entry was unfortunate, at best, as it appears to be misleading. I suspect that many users expect that it means that the file will never be opened and analyzed, but as Konstantin pointe out that isn't the case. "Excluded" files are only unread if they aren't reachable from any analyzed files.

@melWiss
Copy link

melWiss commented Mar 17, 2025

@melWiss

... we have some gigantic generated files, even though they're not analyzed ...

By "not analyzed" do you mean that they are "excluded" from analysis in the analysis options file?

Yes that's what I meant @bwilkerson

@realth000
Copy link

Question: Does it benefits performance if the project is separated into different packages and organize them using dart workspace?

For example, each feature/module is a separate dart package, i have seen this approach in other languages:

packages/
 - feature1
   - pubspec.yaml
   - lib/ ...
 - feature2
   - pubspec.yaml
   - lib/ ...
 - feature3
   - pubspec.yaml
   - lib/ ...
pubspec.yaml  -> pubspec for entire workspace

@bwilkerson
Copy link
Member

Does it benefits performance if the project is separated into different packages and organize them using dart workspace?

If the alternative is to have all of features/modules be separate packages but not part of a workspace, then yes. The benefit of a workspace is that there is a single version solve for all of the packages in the workspace, which means that it's safe for the analyzer to build the element model for each third-party package once and share them across all of the packages. Without that guarantee of a single version solve the analyzer has to build the element model for each third-party package once for every package that has a dependency on it.

If the alternative is to have a single large package with all of the code in each of the separate packages, then no, splitting it into separate packages in a workspace won't change the performance of the analyzer. On the other hand, if splitting the code into multiple packages would help to reduce the number of circular dependencies between pieces of the code, then the reduction in circularities would improve the performance of the analyzer.

@eli1stark
Copy link

@mraleph

We've been experiencing this problem for a while now. We are currently on v3.24.4, so I don't think this is a regression in Flutter 3.29 / Dart 3.7 release. At least for us, it's not. I wanted to share this to add more evidence to the case. Currently, we have refactored a bunch of circular dependencies in our project involving barrel files, we had around 250 individual cases of circular dependency, but as you pointed out, this is very easy to get even without barrel files, as demonstrated by the routing example. I wonder how the analyzer is not stuck completely when circular dependency happens but is still able to recover from this state, even if it takes longer.

@bwilkerson
Copy link
Member

I wonder how the analyzer is not stuck completely when circular dependency happens ...

It effectively analyses everything in the cycle as if it were in a single library.

@nietsmmar
Copy link

I have this problem since upgrading to Flutter 3.29.0. I have no barrel file but I use freezed, json serialization and auto route.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-stability area-dart-model For issues related to conformance to the language spec in the parser, compilers or the CLI analyzer. model-performance Performance/memory issues in analyzer/cfe P2 A bug or feature request we're likely to work on type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests