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

Editor layout is called 5 times opening 1 file #112630

Closed
bpasero opened this issue Dec 16, 2020 · 36 comments
Closed

Editor layout is called 5 times opening 1 file #112630

bpasero opened this issue Dec 16, 2020 · 36 comments
Assignees
Labels
freeze-slow-crash-leak VS Code crashing, performance, freeze and memory leak issues perf workbench-editor-grid Grid layout issues in the editor area
Milestone

Comments

@bpasero
Copy link
Member

bpasero commented Dec 16, 2020

Steps to Reproduce:

  1. add a breakpoint or console.log into editorGroupView.layout
  2. run vscode and have no file open
  3. click on a file from the explorer

=> layout is called 4 times

First one seems legit to me:

editorGroupView.js:1298 Error
    at EditorGroupView.layout (editorGroupView.js:1298)
    at LeafNode.layout (gridview.js:513)
    at VerticalViewItem.layout (splitview.js:76)
    at SplitView.layoutViews (splitview.js:642)
    at SplitView.relayout (splitview.js:549)
    at SplitView.onViewChange (splitview.js:414)
    at splitview.js:472
    at event.js:67
    at Emitter.fire (event.js:456)
    at event.js:44
    at Emitter.fire (event.js:456)
    at Emitter.fire (event.js:459)
    at EditorControl.doSetActiveEditorPane (editorControl.js:107)

But not sure about these:

Error
    at EditorGroupView.layout (editorGroupView.js:1298)
    at LeafNode.layout (gridview.js:513)
    at VerticalViewItem.layout (splitview.js:76)
    at SplitView.layoutViews (splitview.js:642)
    at SplitView.layout (splitview.js:299)
    at BranchNode.layout (gridview.js:216)
    at GridView.layout (gridview.js:619)
    at SerializableGrid.layout (grid.js:172)
    at SerializableGrid.layout (grid.js:437)
    at GridWidgetView.layout (editorPart.js:44)
    at CenteredViewLayout.layout (centeredViewLayout.js:74)
    at EditorPart.doLayout (editorPart.js:810)
    at EditorPart.layout (editorPart.js:805)
    at LeafNode.layout (gridview.js:513)
    at VerticalViewItem.layout (splitview.js:76)
    at SplitView.layoutViews (splitview.js:642)
    at SplitView.layout (splitview.js:299)
    at BranchNode.layout (gridview.js:216)
    at HorizontalViewItem.layout (splitview.js:76)
    at SplitView.layoutViews (splitview.js:642)
    at SplitView.relayout (splitview.js:549)
    at SplitView.onViewChange (splitview.js:414)

Also adding Isi since this is maybe the centered grid layout.

@bpasero bpasero added the workbench-editor-grid Grid layout issues in the editor area label Dec 16, 2020
@bpasero
Copy link
Member Author

bpasero commented Dec 16, 2020

This is bad for the work to support vertical tabs in #106448 because the layout will be expensive when tabs wrap.

@joaomoreno
Copy link
Member

I remember spending a lot of time making sure this wouldn't happen, as far as the grid goes. Sucks if it broke. I can take a peek.

@joaomoreno joaomoreno added this to the January 2021 milestone Dec 17, 2020
@joaomoreno joaomoreno added bug Issue identified by VS Code Team member as probable bug perf labels Dec 17, 2020
@joaomoreno
Copy link
Member

joaomoreno commented Jan 27, 2021

I actually see 6 calls to layout, this is preposterous. The last 2 are calls via relayout (what does that even mean?).

@joaomoreno
Copy link
Member

joaomoreno commented Jan 27, 2021

Currently investigating the first 4 layout calls which are all in the same stack frame.

But those last 2 layout calls from relayout sound unnecessary and we should try to clean that up and make sure the only time layout gets calls, it has all the knowledge it needs to make the right decisions, instead of us having to call it later.

@bpasero
Copy link
Member Author

bpasero commented Jan 27, 2021

@joaomoreno I agree with reducing calls to relayout as much as possible. relayout should only be called if the title control knows for a fact that something has changed that impacts the entire splitview.

I am not sure about the doLayout reference you pointed me to. That is just a way to schedule repeated layout calls on the next animation frame and is meant to reduce perf overhead of this method. It is the one calling this method (layout) that should not be called more than once.

@joaomoreno
Copy link
Member

@bpasero This is the stack of that call:

 Error
    at EditorGroupView.layout (file:///home/joao/Work/vscode/out/vs/workbench/browser/parts/editor/editorGroupView.js:1298:35)
    at EditorGroupView.relayout (file:///home/joao/Work/vscode/out/vs/workbench/browser/parts/editor/editorGroupView.js:1313:22)
    at TabsTitleControl.doLayout (file:///home/joao/Work/vscode/out/vs/workbench/browser/parts/editor/tabsTitleControl.js:1041:28)
    at AnimationFrameQueueItem._runner (file:///home/joao/Work/vscode/out/vs/workbench/browser/parts/editor/tabsTitleControl.js:1011:26)
    at AnimationFrameQueueItem.execute (file:///home/joao/Work/vscode/out/vs/base/browser/dom.js:147:22)
    at animationFrameRunner (file:///home/joao/Work/vscode/out/vs/base/browser/dom.js:183:21)

Which runs after all other 5 calls run, so it seems it's just unnecessary, given the grid within has already been laid out correctly.

@joaomoreno joaomoreno assigned bpasero and unassigned isidorn Jan 27, 2021
@joaomoreno
Copy link
Member

Repro case:

  1. Have no editors open
  2. Open a text editor

🐛 6 calls to layout appear!


There are 3 separate causes to the 6 layout calls:

  1. Grid: I found that the grid is indeed calling too many layout calls into its views. This must've crept up over time and can be fixed by having some sort of SplitViewOptions.manualLayout?: boolean option. Once that is fixed, we will reduce 6 to 4 calls. @joaomoreno
  2. Grid within grid: The editor group node within the workbench grid first reports having changed its size, due to it being about to open an editor, which causes a layout. Then, the editor node within the editor grid reports having changed its size, due to it being about to open a text editor; this then propagate to the outer workbench grid causing a second layout. This really only happen when going from 0 to 1 editor in the group. This is hard to fix.
  3. Combination with breadcrumbs and wrapping tabs: There is code in TabsTitleControl to measure the title bar height due to the new wrapping tabs feature. Unfortunately there is also code in there to relayout whenever breadcrumbs appear and disappear. The combination of these two code paths cause two additiopnal layout calls, despite neither the breadcrumbs state nor wrapping tabs height actually change in 0 to 1 editor case. @bpasero

@bpasero
Copy link
Member Author

bpasero commented Jan 27, 2021

Thanks, I will look into the relayout issues.

joaomoreno added a commit that referenced this issue Jan 27, 2021
related to #112630
@jrieken
Copy link
Member

jrieken commented Jan 27, 2021

Unfortunately there is also code in there to relayout whenever breadcrumbs appear and disappear

@joaomoreno Do you mean when breadcrumbs are enabled/disabled or also when their content changes? In the case of the former we might assume that breadcrumbs are enabled. Surely this code was written when they were off by default.

Out of curiosity: it is always good to prevent unneeded calls, but do have a chance to protect yourself from such calls, e.g early return when layout is called with the input? I feel without that you are repeatedly encountering this because stuff just rots

@joaomoreno
Copy link
Member

@joaomoreno Do you mean when breadcrumbs are enabled/disabled or also when their content changes? In the case of the former we might assume that breadcrumbs are enabled. Surely this code was written when they were off by default.

Yeah that makes sense. What I observed was that the breadcrumbs code was assuming something has changed, even though nothing changes regarding breadcrumbs when going from 0 to 1 editor.

Out of curiosity: it is always good to prevent unneeded calls, but do have a chance to protect yourself from such calls, e.g early return when layout is called with the input? I feel without that you are repeatedly encountering this because stuff just rots

Totally. This occurs now due to rot. Yeah I'll see if I can protect a bit better here.

@jrieken
Copy link
Member

jrieken commented Jan 28, 2021

What I observed was that the breadcrumbs code was assuming something has changed, even though nothing changes regarding breadcrumbs when going from 0 to 1 editor.

Breadcrumbs does that because per editor input it might be hidden, e.g when you open an extension editor it needs to hide, and that needs to relayout to return the screen real-estate (or take it back). Tho, surely can be done smarter

@bpasero
Copy link
Member Author

bpasero commented Feb 1, 2021

@jrieken I think breadcrumbsControl#update is returning true wrongly though. From the location where it is called the comment indicates: relayout when we have a breadcrumbs and when update changed its hidden-status

But in reality you return true always even when the visibility does not change. Can you change that please?

@bpasero
Copy link
Member Author

bpasero commented Feb 19, 2021

@jrieken thanks, I pushed another change to avoid repeated relayout calls from breadcrumbs, specifically this call is no longer needed...

this.group.relayout(); // relayout when we have a breadcrumbs and when update changed its hidden-status

...because ever since tabs can wrap, there is logic in the layout call that will trigger a relayout automatically once the height has changed from the last layout run:

And that should take care of breadcrumbs too.

I tested this briefly (jumping between normal text editor and untitled file) and couldn't find any issues, but maybe you could also give it a test.

The remaining layout calls seem to originate from the grid, so leaving up to Joao to decide wether we want / can improve that.

@bpasero bpasero removed their assignment Feb 19, 2021
@jrieken
Copy link
Member

jrieken commented Feb 22, 2021

I tested this briefly (jumping between normal text editor and untitled file) and couldn't find any issues, but maybe you could also give it a test.

Cool. I will keep an eye open

@jrieken
Copy link
Member

jrieken commented May 7, 2021

"fixed", at least breadcrumbs isn't triggering this eagerly anymore. Tho, when opening 1 file I count 6(!) layout calls and I'd say opening files is a more common scenario.

@joaomoreno question: layout is about sizing and positioning child elements, right? So, by no means I support calling layout unnecessarily but isn't layout a good candidate for caching dimensions and then ignoring subsequent calls with the same dimensions?

@joaomoreno
Copy link
Member

@joaomoreno question: layout is about sizing and positioning child elements, right? So, by no means I support calling layout unnecessarily but isn't layout a good candidate for caching dimensions and then ignoring subsequent calls with the same dimensions?

Definitely, the question is where should that be? In the widgets themselves? In the widget components? In the workbench components? Everywhere? 🙈

@joaomoreno
Copy link
Member

"fixed", at least breadcrumbs isn't triggering this eagerly anymore. Tho, when opening 1 file I count 6(!) layout calls and I'd say opening files is a more common scenario.

So weird. I kept seeing only one. I commented all my settings, then I started seeing 2. I reverted my settings change and now I see 2 all the time. Second one is the relayout mentioned above:

Error
    at EditorGroupView.layout (editorGroupView.js:1351)
    at EditorGroupView.relayout (editorGroupView.js:1366)
    at TabsTitleControl.doLayout (tabsTitleControl.js:1053)
    at AnimationFrameQueueItem._runner (tabsTitleControl.js:1023)
    at AnimationFrameQueueItem.execute (dom.js:147)
    at animationFrameRunner (dom.js:183)

@joaomoreno
Copy link
Member

joaomoreno commented May 7, 2021

"fixed", at least breadcrumbs isn't triggering this eagerly anymore. Tho, when opening 1 file I count 6(!) layout calls and I'd say opening files is a more common scenario.

We figured out in Slack:

  • The scenario tested in this issue is: workbench startup
  • Joh (and I) see 6 calls when opening a file by clicking it in the explorer, which is a separate scenario. We should have a new issue for this.

@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

But my initial steps indicate the scenario, it is not startup, but opening a file:

Steps to Reproduce:

1. add a breakpoint or `console.log` into `editorGroupView.layout`
2. run vscode and have no file open
3. click on a file from the explorer

I see the following layout calls now from a fresh workspace when I open the first file:

Error
    at EditorGroupView.layout (editorGroupView.ts:1758)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.relayout (splitview.ts:781)
    at SplitView.onViewChange (splitview.ts:616)
    at splitview.ts:692
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at EditorControl.doSetActiveEditorPane (editorControl.ts:147)
    at EditorControl.doShowEditorPane (editorControl.ts:84)
    at EditorControl.openEditor (editorControl.ts:63)
    at editorGroupView.ts:1001
    at EditorGroupView.doShowEditor (editorGroupView.ts:1016)
    at EditorGroupView.doOpenEditor (editorGroupView.ts:982)
    at EditorGroupView.openEditor (editorGroupView.ts:910)
    at EditorService.openEditor (editorService.ts:629)
    at async DelegatingEditorService.editorOpenHandler (explorerViewlet.ts:224)

Error
    at EditorGroupView.layout (editorGroupView.ts:1758)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at GridView.layout (gridview.ts:936)
    at SerializableGrid.layout (grid.ts:253)
    at SerializableGrid.layout (grid.ts:555)
    at GridWidgetView.layout (editorPart.ts:74)
    at CenteredViewLayout.layout (centeredViewLayout.ts:98)
    at EditorPart.doLayout (editorPart.ts:1096)
    at EditorPart.layout (editorPart.ts:1089)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.relayout (splitview.ts:781)
    at SplitView.onViewChange (splitview.ts:616)
    at splitview.ts:692
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at EditorControl.doSetActiveEditorPane (editorControl.ts:147)
    at EditorControl.doShowEditorPane (editorControl.ts:84)
    at EditorControl.openEditor (editorControl.ts:63)
    at editorGroupView.ts:1001
    at EditorGroupView.doShowEditor (editorGroupView.ts:1016)
    at EditorGroupView.doOpenEditor (editorGroupView.ts:982)
    at EditorGroupView.openEditor (editorGroupView.ts:910)
    at EditorService.openEditor (editorService.ts:629)
    at async DelegatingEditorService.editorOpenHandler (explorerViewlet.ts:224)

Error
    at EditorGroupView.layout (editorGroupView.ts:1758)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at GridView.layout (gridview.ts:936)
    at SerializableGrid.layout (grid.ts:253)
    at SerializableGrid.layout (grid.ts:555)
    at GridWidgetView.layout (editorPart.ts:74)
    at CenteredViewLayout.layout (centeredViewLayout.ts:98)
    at EditorPart.doLayout (editorPart.ts:1096)
    at EditorPart.layout (editorPart.ts:1089)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at HorizontalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.relayout (splitview.ts:781)
    at SplitView.onViewChange (splitview.ts:616)
    at splitview.ts:692
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at EditorControl.doSetActiveEditorPane (editorControl.ts:147)
    at EditorControl.doShowEditorPane (editorControl.ts:84)
    at EditorControl.openEditor (editorControl.ts:63)
    at editorGroupView.ts:1001
    at EditorGroupView.doShowEditor (editorGroupView.ts:1016)
    at EditorGroupView.doOpenEditor (editorGroupView.ts:982)
    at EditorGroupView.openEditor (editorGroupView.ts:910)
    at EditorService.openEditor (editorService.ts:629)
    at async DelegatingEditorService.editorOpenHandler (explorerViewlet.ts:224)

Error
    at EditorGroupView.layout (editorGroupView.ts:1758)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at GridView.layout (gridview.ts:936)
    at SerializableGrid.layout (grid.ts:253)
    at SerializableGrid.layout (grid.ts:555)
    at GridWidgetView.layout (editorPart.ts:74)
    at CenteredViewLayout.layout (centeredViewLayout.ts:98)
    at EditorPart.doLayout (editorPart.ts:1096)
    at EditorPart.layout (editorPart.ts:1089)
    at LeafNode.layout (gridview.ts:781)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at HorizontalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.layout (splitview.ts:473)
    at BranchNode.layout (gridview.ts:380)
    at VerticalViewItem.layout (splitview.ts:138)
    at SplitView.layoutViews (splitview.ts:911)
    at SplitView.relayout (splitview.ts:781)
    at SplitView.onViewChange (splitview.ts:616)
    at splitview.ts:692
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at event.ts:56
    at event.ts:91
    at event.ts:91
    at Emitter.fire (event.ts:622)
    at event.ts:56
    at Emitter.fire (event.ts:622)
    at Emitter.fire (event.ts:624)
    at EditorControl.doSetActiveEditorPane (editorControl.ts:147)
    at EditorControl.doShowEditorPane (editorControl.ts:84)
    at EditorControl.openEditor (editorControl.ts:63)
    at editorGroupView.ts:1001
    at EditorGroupView.doShowEditor (editorGroupView.ts:1016)
    at EditorGroupView.doOpenEditor (editorGroupView.ts:982)
    at EditorGroupView.openEditor (editorGroupView.ts:910)
    at EditorService.openEditor (editorService.ts:629)
    at async DelegatingEditorService.editorOpenHandler (explorerViewlet.ts:224)

Error
    at EditorGroupView.layout (editorGroupView.ts:1758)
    at EditorGroupView.relayout (editorGroupView.ts:1776)
    at TabsTitleControl.doLayout (tabsTitleControl.ts:1371)
    at AnimationFrameQueueItem._runner (tabsTitleControl.ts:1332)
    at AnimationFrameQueueItem.execute (dom.ts:210)
    at animationFrameRunner (dom.ts:250)

That is 5 layout calls.

@bpasero bpasero changed the title Editor layout is called 3 times opening 1 file Editor layout is called 5 times opening 1 file May 7, 2021
@joaomoreno
Copy link
Member

Right, looking again.

@joaomoreno joaomoreno self-assigned this May 7, 2021
@joaomoreno joaomoreno added this to the May 2021 milestone May 7, 2021
@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

The last one is interesting for maybe me+Jo, we first assume a height of 35px in the title control but then breadcrumbs appear and we layout because that changes the height. But I think this probably only happens on the very first editor opening.

@jrieken
Copy link
Member

jrieken commented May 7, 2021

We should just assume that breadcrumbs are on - as they are by default- or read the config sooner. What I don't know is what we are laying out here. Isn't the title, breadcrumbs, and the editor-widget inside a single grid element and isn't that element already sized? What are we resizing/re-layouting here?

@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

As for the thing I am looking at (the "relayout" triggered from the title control), that one is only triggering a relayout of the widgets inside the grid, not the entire grid. And the reason is this:

  • a layout comes in to the editor grid (for whatever reason)
  • we need to layout title control (which includes breadcrumbs) and editor control
  • it is important that the editor control gets the exact height of the entire height available in the editor group minus the title control height
  • as such we first ask title to layout and return its height
  • title control runs the layout but for perf reasons async (in a next animation frame)
  • since it is the first time we run a layout, we haven't figured out if breadcrumbs are visible or not so we just return 35px (at this point we can probably work on a fix)
  • editor gets the layout with total height minus 35px
  • next animation frame the real title control layout runs and figures out breadcrumbs are visible so it kicks off a relayout given the height has changed
  • editor widget gets layout with the correct height now that breadcrumbs are visible

@joaomoreno
Copy link
Member

title control runs the layout but for perf reasons async (in a next animation frame)

Why is this? Entire complex widgets (splitview and list) layout in a sync fashion and a title bar doesn't? Can't you actually compute how much height you need instantly?

@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

@joaomoreno I am all up for changing the tabs widget to use a list, but there are some things that it does which made me put the layout code into a "schedule at next animation frame"

  • always keep the active tab revealed (requires me to access DOM properties that can trigger layout)
  • allow tabs to wrap which requires to access DOM properties for getting the height that can trigger again a browser layout
  • update the custom scrollbar to reflect what is going on (I guess that is something the list/tree also do well)

@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

It's a bit unfair that the async layout is also used for breadcrumbs because that is exactly why the relayout triggers: we only figure out that breadcrumbs are there when the animation frame executes, but we could run that part of the layout sync. I think a better way would be to only keep that code async where we know that DOM properties are accessed that can trigger a browser layout.

@jrieken
Copy link
Member

jrieken commented May 7, 2021

that it does which made me put the layout code into a "schedule at next animation frame"

Some FYI - running at next animation frame doesn't give you a guarantee that the DOM is pretty and that asking for layout info isn't expensive. It might well be that someone already modified the DOM so that an expensive re-compute is required but it is much less likely. I found this nice article a while back (https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing) I then added dom#measure and dom#modify but those utils never became popular 😢

@bpasero
Copy link
Member Author

bpasero commented May 7, 2021

@jrieken interesting, are you suggesting that I should be then using dom#measure in the layout call for tabs? I actually do not modify the dom in the layout method, I mainly measure.

@jrieken
Copy link
Member

jrieken commented May 7, 2021

Yeah, the idea is to do all measuring on a "fresh" layout and do all modifications after that. Tho, we need to onboard all components to see the full effect of this

@joaomoreno
Copy link
Member

Fixed this all the way down to two layout calls: the actual one and the delayed one from @bpasero.

@joaomoreno joaomoreno assigned bpasero and unassigned joaomoreno May 10, 2021
joaomoreno added a commit that referenced this issue May 10, 2021
joaomoreno added a commit that referenced this issue May 10, 2021
@bpasero
Copy link
Member Author

bpasero commented May 10, 2021

👏 ❤️

@bpasero
Copy link
Member Author

bpasero commented May 14, 2021

This looks a lot lot better now, I verified that clicking on a file when no file is opened now only calls the layout method once and this originates from a relayout from the tabs title control itself.

However, I went down the path trying to avoid the relayout by making the breadcrumbs layout sync, leaving the tabs layout async (which I still prefer given issues such as #34745) and then in the end realised that even with a sync breadcrumbs layout, the relayout still happens. The reason is quite simple and I originally didn't think about it: when an editor opens, we actually do not go through the normal layout call from the editor group because no dimensions change (all we do is open an editor). However, when an editor opens with breadcrumbs, it will result in different dimensions for the title area compared to when no editor is open (57px vs 35px) and as such a relayout is triggered to signal this to all controls that are layed out in the editor group.

But the good news is, that this call of relayout for the first editor is actually a no-op:

  • since no editor is yet opened at that time, nothing happens in the editor control
  • the re-entrant layout call to the tabs title control is also not doing anything because we are in a layout call already

Since the relayout flow is still needed for the case when 1 editor is opened with breadcrumbs and you open a second editor without breadcrumbs (e.g. when opening an untitled file), I will stay away from making further changes here.

@bpasero bpasero closed this as completed May 14, 2021
@github-actions github-actions bot locked and limited conversation to collaborators Jun 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
freeze-slow-crash-leak VS Code crashing, performance, freeze and memory leak issues perf workbench-editor-grid Grid layout issues in the editor area
Projects
None yet
Development

No branches or pull requests

4 participants