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

TabsTitleControl.layout() slows down editor resize #34745

Closed
alexdima opened this issue Sep 21, 2017 · 15 comments
Closed

TabsTitleControl.layout() slows down editor resize #34745

alexdima opened this issue Sep 21, 2017 · 15 comments
Assignees
Labels
bug Issue identified by VS Code Team member as probable bug perf workbench-tabs VS Code editor tab issues
Milestone

Comments

@alexdima
Copy link
Member

  • open a diff editor (side-by-side)
  • resize via sash:
    kapture 2017-09-21 at 12 08 09

  • now open two editors side-by-side
  • resize via sash:
    kapture 2017-09-21 at 12 20 16

Most of the time is spent in two things:

image

@alexdima
Copy link
Member Author

Note: the time TabsTitleControl.layout takes is significantly larger when using the steps in #34716

i.e. 3K+ code lenses.

@bpasero
Copy link
Member

bpasero commented Sep 22, 2017

@alexandrudima looks like most time is spend in this call:

image

I am happy for advice how to avoid that. The tab title control is a display:flex container that lays out all tabs. I have seen performance issues before at this location and it seems worse the more tabs are opened.

I need the offsetWidth to update the scrollbar properly that shows when tabs overflow.

Maybe one idea is to buffer the layout calls and not run them sync from the mouse move listener in the sash widget.

/cc @joaomoreno

@alexdima
Copy link
Member Author

@bpasero I use various tricks to avoid sync forced layout:

  • measuring unknown width/height things at creation time. i.e. if a new tab is added with a custom label, the tab width can be measured when the tab is created/added. If a tab is modified to have a different label, the width can be measured at the modification time.
  • keeping track of known widths. If the workbench gets resized, the width of the tabs area can be saved in memory and the DOM would not need to be queried.

IMHO those two bullet points should cover the computation of scrollWidth (sum of all tabs width) and width (this is something the workbench knows)

@joaomoreno
Copy link
Member

joaomoreno commented Sep 22, 2017

keeping track of known widths

Yeah, the width should actually only be measured at the top level of a layout() call chain. Every step down that chain should split that width up accordingly. The TabsTitleControl.layout() method should take a dimension as an argument. And its caller, EditorGroupsControl, should pass in the correct dimensions when calling layout, since he already knows those dimensions.

@bpasero
Copy link
Member

bpasero commented Sep 29, 2017

The expensive part is indeed the call to scrollWidth where Chrome has to compute the size of each tab. Knowing the size of the container is not enough so it turns out to be a matter of caching the sizes for each tab when the tab changes.

@jrieken jrieken added the important Issue identified as high-priority label Nov 2, 2017
@jrieken
Copy link
Member

jrieken commented Nov 2, 2017

This is really bad. When opening/reloading the workbench with just one tab, ~50ms are spend. That makes it the most expensive single call after code loading and garbage collection.

screen shot 2017-11-02 at 17 09 22

title.cpuprofile.txt

@bpasero
Copy link
Member

bpasero commented Nov 2, 2017

@jrieken interestingly as soon as I move that layout call into a setTimeout(0) the code is much faster. So just the fact that we force a layout in Chrome (by asking for tabsContainer.scrollWidth) during window startup causes a performance of 50ms vs. 0.xms in the other case...

@jrieken
Copy link
Member

jrieken commented Nov 3, 2017

The timeline tool tells me that it's causing re-layouts. So with some setTimeout-tricks you might be lucky and get a layout-ed state but I believe the problem is some html-properties are accessed that cause the browser to relayout the whole page.

screen shot 2017-11-03 at 08 53 58

@bpasero bpasero modified the milestones: On Deck, November 2017 Nov 6, 2017
@jrieken
Copy link
Member

jrieken commented Nov 14, 2017

Should we consider something like https://github.com/wilsonpage/fastdom?

@bpasero
Copy link
Member

bpasero commented Nov 14, 2017

@jrieken I think fastdom is the equivalent of our scheduleAtNextAnimationFrame where you can batch operations to run on the next animation frame.

@bpasero
Copy link
Member

bpasero commented Nov 15, 2017

Pushed 2 changes:

  • for startup: scheduling the layout at next animation frame to avoid the critical path (f54d16c)
  • found an issue where within the layout method I would force 2 full layouts because the way code was ordered (8142724)

The fix of avoiding a second layout call brings some nice performance boost for resizing of editors.

Previously
image

Now
image

The remaining performance issue with tabs is the fact that we access offsetWidth as well as scroll via scrollLeft. The only fix here is to:

  • scroll via absolute positioning (negative left)
  • remove flex and implement absolute pixel layout for the tabs
  • implement custom auto-scrolling behaviour (e.g. when doing DND and reaching tabs that are scrolled away)

I am not a big fan of going away from flex, so I will stop here for now.

@jrieken I extracted the startup perf issue into #38404 so that we have something to close and verify for November. I will keep this issue open and restore it how it was before.

@bpasero bpasero removed this from the November 2017 milestone Nov 15, 2017
@bpasero bpasero added workbench-tabs VS Code editor tab issues bug Issue identified by VS Code Team member as probable bug and removed workbench important Issue identified as high-priority labels Nov 15, 2017
@roblourens roblourens added the verified Verification succeeded label Dec 6, 2017
@bpasero bpasero removed the verified Verification succeeded label Dec 19, 2017
@bpasero bpasero closed this as completed Jun 2, 2018
@jrieken
Copy link
Member

jrieken commented Jun 4, 2018

I will keep this issue open and restore it how it was before.

@bpasero Did we make further improvements to this or why is this closed?

@bpasero
Copy link
Member

bpasero commented Jun 4, 2018

Did not want to close this actually, the performance is pretty much the same as before grid land:

image

@bpasero bpasero reopened this Jun 4, 2018
@bpasero bpasero added this to the Backlog milestone Feb 19, 2022
@bpasero bpasero changed the title TabsTitleControl.layout slows down editor resize TabsTitleControl.layout() slows down editor resize Sep 14, 2022
@bpasero
Copy link
Member

bpasero commented Dec 6, 2022

Talked with Alex and he is 👍 to close this issue given the changes I have made so far, esp. c35e63f has helped in my measurement.

@bpasero bpasero closed this as completed Dec 6, 2022
@alexdima
Copy link
Member Author

alexdima commented Dec 6, 2022

Yes, the layout is a lot faster for me now:
image

@github-actions github-actions bot locked and limited conversation to collaborators Jan 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue identified by VS Code Team member as probable bug perf workbench-tabs VS Code editor tab issues
Projects
None yet
Development

No branches or pull requests

5 participants