-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Ensure that MEF is initialized using an old style non-async package #1560
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using System; | ||
using System.Runtime.InteropServices; | ||
using GitHub.VisualStudio.UI; | ||
using Microsoft.VisualStudio.Shell; | ||
using Microsoft.VisualStudio.ComponentModelHost; | ||
|
||
namespace GitHub.VisualStudio | ||
{ | ||
/// <summary> | ||
/// This is the host package for the <see cref="GitHubPane"/> tool window. | ||
/// </summary> | ||
/// <remarks> | ||
/// We auto-load this package before its tool window is activated to ensure that MEF has | ||
/// been initialized and the tool window won't be blamed for degrading startup performance. | ||
/// See: https://github.com/github/VisualStudio/issues/1550 | ||
/// </remarks> | ||
[PackageRegistration(UseManagedResourcesOnly = true)] | ||
[Guid(Guids.InitializeMefPackageId)] | ||
// This package must auto-load before its tool window is activated on startup. | ||
// We're using the GitSccProvider UI context because this is triggered before | ||
// tool windows are activated and we already use it elsewhere (the containing | ||
// assembly would have been loaded anyway). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VS Shell will already ensure your package is loaded before the tool window is activated so you don't have to do it here. This auto load ensures that your package is loaded for every startup session regardless of your tool window is open slowing down startup for all users instead of just those with the toolwindow visible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If we allow that to happen, our package gets blamed for MEF initialization (which can take 10 seconds 😨).
We need to auto-load on this context anyway in order to install a custom There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As you pointed, the cost is still there just becomes part of SCC package which is unique in this case since it is the one that causes your auto load unlike other scenarios. At the end of the day startup is still impacted by 10 seconds which is the important part. I have to mention that SCC hiding cost of auto loads from the UI context it sets is a known issue that we will fix soon btw. As for your auto load reason, would you be able to use a rule based UI context to activate your UI context instead of auto loading a package? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Thanks, this is good to know.
Our UI context is a subset of the Am I correct in thinking that a rule based UI context is a composite of existing UI context (you can't use them to create a completely custom context)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are the conditions that you set the UI context in? If it is GIT SCC context and presence of your package, you can just define a rule based UI contexts that is only based on GIT SCC context. Since the rule based UI context will only be added when your pkgdef is deployed it will only be active when GIT SCC is active and user has your extension installed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Here is pseudo code for what we need: We're pretty much always in the We have made efforts to only load when absolutely necessary! 😄 |
||
[ProvideAutoLoad(Guids.GitSccProviderId)] | ||
[ProvideToolWindow(typeof(GitHubPane), Orientation = ToolWindowOrientation.Right, | ||
Style = VsDockStyle.Tabbed, Window = EnvDTE.Constants.vsWindowKindSolutionExplorer)] | ||
public sealed class GitHubPanePackage : Package | ||
{ | ||
/// <summary> | ||
/// Ensure that MEF is initialized using an old style non-async package. | ||
/// This causes the `Scanning new and updated MEF components...` dialog to appear. | ||
/// Without this the GitHub pane will be blamed for degrading startup performance. | ||
/// Initialize must be called before its tool window is activated (otherwise the | ||
/// tool window still end up waiting for it). | ||
/// </summary> | ||
protected override void Initialize() | ||
{ | ||
GetService(typeof(SComponentModel)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove this line and fix the tool window to not synchronously block on this service? Your tool window initialization could display something else while asynchronously awaiting MEF's initialization, thus the user experience is that VS starts up much more quickly, even if github's tool window is visible. |
||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not approve this change as this doesn't really solve any performance issues. In fact it seems to make things worse as it adds synchronous query of MEF to startup path for those users that have Git provider set as default source control provider.