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

FEATURE: On-demand projects loading when working with big C# codebases #1316

Closed
dmgonch opened this issue Oct 14, 2018 · 12 comments
Closed

FEATURE: On-demand projects loading when working with big C# codebases #1316

dmgonch opened this issue Oct 14, 2018 · 12 comments

Comments

@dmgonch
Copy link
Contributor

dmgonch commented Oct 14, 2018

PROBLEM DESCRIPTION: One of the major factors contributing to VSCode success is its speed. For JavaScript for example users get rich development experience almost immediately after launching the IDE. When working with C# codebases though developers have to wait for ALL projects to be loaded until many code navigation features are available. For codebase containing more than few dozens of projects this delay is very significant. This experience gets even worse when a developer often switches b/w branches which is a common place when working with Git. After checking out a branch, Ominsharp would need to potentially reload many projects which can take minutes. And in bigger codebases a user typically only needs to only work with a small subset of the code, particularly if s/he is only browsing/studying it. The workarounds of opening multiple instances of VSCode rooted in particular subfolders or managing a list of designated folders in a workspace creates unnecessary friction in developer workflow particularly when s/he needs to quickly "jump" b/w various places in the codebase (which is often the case when doing codereviews).

PROPOSED EXPERIENCE: One approach for improving the experience described above is to allow user to control whether all projects loaded automatically. When automatic loading is disabled VSCOde could only start loading projects for files when they are opened in the IDE for editing (including all referenced projects recursively). This could be done for example by looking for a csproj file in the same folder where the opened for editing file is located or walk up the folder hierarchy until such project file is found. The PROS of this approach is that VSCode will load only projects for the source code that user is working on without wasting time on projects are not relevant at the moment. Should the user need to switch the current branch or restart VSCode, s/he can get back to the working environment much faster. The obvious CONS of this approach is that user might be getting incomplete semantic information for example when IDE shows references for symbols. Arguably though when reviewing code or working on a particular component in a bigger codebase this could be a good compromise comparing to always getting full list of references for the cost of many minute wait (and draining battery when on laptop) while this information might not be needed at all. Allowing user to make this choice seems like the right thing to do and the prototype of this approach that I was using with the codebase containing almost 800 C# projects for last few months confirms this for me.

DESIGN: Introduce new VSCode setting omnisharp.EnableOnDemandMsBuildProjectsLoad with default value 'false' which will ensure the existing projects loading behavior. When the setting is set to 'true' VSCode will behave as described above and will load only projects relevant to files that are currently opened in the IDE.
The new setting will be passed to OnlySharp.exe (into OmniSharp.MSBuild.ProjectSystem via IConfiguration) using existing configuration key, i.e.: OmniSharp.exe MsBuild:OnDemandProjectsLoad. When the setting is changed, VSCode will prompt user to restart the IDE for the change to take place.

@akshita31
Copy link
Contributor

@dmgonch In my opinion, prompting the user to restart OmniSharp process when the configuration changes, should be enough I think, we shouldn't need to restart the IDE.

@dmgonch
Copy link
Contributor Author

dmgonch commented Oct 15, 2018

@akshita31 : agreed - I just wasn't sure if restarting of just OmniSharp process is currently supported in the VSCode extension.

@dmgonch
Copy link
Contributor Author

dmgonch commented Oct 16, 2018

@rchande @DustinCampbell @david-driscoll : folks, I would appreciate any additional feedback for the proposal.

@rchande
Copy link

rchande commented Oct 17, 2018

@dmgonch This sounds reasonable to me. If you're interested in generally making project load faster (instead of optimizing for the hundreds of projects case), there are a few other things you can consider:

  • Use "Design-Time Batch Build" APIs to take advantage of the new batch builds feature in MSBuild
  • Build/load projects in parallel now that cross-plat MSBuild parallelism works
  • Use MSBuild to generate the project dependency graph after all the projects are loaded, and write the graph to disk. On subsequent loads, use this graph to optimize load order (the current load order is totally arbitrary).

@dmgonch
Copy link
Contributor Author

dmgonch commented Oct 19, 2018

@rchande: indeed those are good performance optimization items to consider. I believe though the scenario that I outlined is less about making projects to load/build faster but more about avoiding loading/building projects until a user starts working with them.
@DustinCampbell: hopefully you had a chance to take a look at this write-up as well. I just want to avoid surprises later when PR is out. Thanks!

@DustinCampbell
Copy link
Contributor

I did take a look, yes. @rchande and I sat down and discussed the issue before he replied.

@dmgonch
Copy link
Contributor Author

dmgonch commented Nov 2, 2018

@filipw : not sure if you had a chance to take a look. Would appreciate any feedback on the feature itself and the proposed implementation. Thanks!

@dmgonch
Copy link
Contributor Author

dmgonch commented Dec 29, 2018

Closing since the feature has been implemented and merged into master.

@dmgonch dmgonch closed this as completed Dec 29, 2018
@dmgonch dmgonch changed the title FEATURE PROPOSAL: Smart/configurable projects loading when working with big C# codebases FEATURE PROPOSAL: On-demand projects loading when working with big C# codebases Jan 4, 2019
@dmgonch dmgonch changed the title FEATURE PROPOSAL: On-demand projects loading when working with big C# codebases FEATURE: On-demand projects loading when working with big C# codebases Jan 4, 2019
@gmkado
Copy link

gmkado commented Feb 22, 2023

@dmgonch huge fan of this feature, it makes navigating my huge codebase much quicker. What do you think about an option to load projects on demand first, then once thats done loading the remaining projects in the background so you eventually get all references?

@dmgonch
Copy link
Contributor Author

dmgonch commented Feb 23, 2023

@gmkado the key question I think is how to select the relevant subset of those "remaining projects" to load in the background. When working with a codebase containing thousands of projects, I actually don't want to load all of them, even in the background, since I never need to look into the majority of them.

@gmkado
Copy link

gmkado commented Feb 24, 2023

@dmgonch I was thinking you would load everything in the solution, but prioritize open files (i.e. if another file got opened, those projects got bumped to the top of the queue). This could take the form of another config ContinueLoadingAfterOnDemandCompletes (naming things is hard) that would give you this option, but would default to false. So the current behavior would stay the same.

I'm not familiar with how omnisharp works behind the scenes, so maybe this is impractical. But it would be nice for "medium-large" sized codebases to get the speed advantage of the on-demand feature, and where leaving omnisharp to think long enough would eventually get everything loaded.

@dmgonch
Copy link
Contributor Author

dmgonch commented Feb 26, 2023

To tell the truth I never needed such a functionality though I agree that it might be practical for 'not so large' set of projects. On the other hand, in codebases even with 1000s of projects, searching files by name (Ctrl-P on Windows) combined with enableMsBuildLoadProjectsOnDemand was good enough for me (though I'm still yearning for the proper cross-language online symbols search integration in VSCode).
Additionally, many very large codebases I work with don't have solution files at all and 'glue' projects together using https://github.com/microsoft/MSBuildSdks/tree/main/src/Traversal and generate SLN files on the fly using https://github.com/microsoft/SlnGen

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

No branches or pull requests

5 participants