Closed
Bug 1462374
Opened 7 years ago
Closed 6 years ago
1.05ms uninterruptible reflow at _adjustFocusAfterTabSwitch@chrome://browser/content/tabbrowser.js:1200:5
Categories
(Firefox :: Tabbed Browser, defect, P5)
Tracking
()
People
(Reporter: geeknik, Assigned: Gijs)
References
(Blocks 1 open bug)
Details
(Whiteboard: [ohnoreflow][fxperf:p2])
Here's the stack:
_adjustFocusAfterTabSwitch@chrome://browser/content/tabbrowser.js:1200:5
updateDisplay/<@resource:///modules/AsyncTabSwitcher.jsm:425:15
set_selectedIndex@chrome://browser/content/tabbrowser.xml:2329:13
set_selectedPanel@chrome://global/content/bindings/tabbox.xml:641:13
set_selectedIndex@chrome://global/content/bindings/tabbox.xml:386:15
set_selectedItem@chrome://global/content/bindings/tabbox.xml:411:34
set_selectedTab@chrome://global/content/bindings/tabbox.xml:100:15
set selectedTab@chrome://browser/content/tabbrowser.js:250:5
_blurTab@chrome://browser/content/tabbrowser.js:3035:24
_beginRemoveTab@chrome://browser/content/tabbrowser.js:2754:5
removeTab@chrome://browser/content/tabbrowser.js:2678:10
onxblclick@chrome://browser/content/tabbrowser.xml:1062:11
Updated•7 years ago
|
Whiteboard: [ohnoreflow][qf][photon-performance] → [ohnoreflow][qf][fxperf]
Updated•6 years ago
|
Whiteboard: [ohnoreflow][qf][fxperf] → [ohnoreflow][qf:p1][qf:f64][fxperf]
Updated•6 years ago
|
Component: Untriaged → Tabbed Browser
Comment 1•6 years ago
|
||
This appears to be a (necessary) focus call. Not sure this bug is actionable.
Priority: -- → P5
Assignee | ||
Comment 2•6 years ago
|
||
(In reply to Dão Gottwald [::dao] from comment #1)
> This appears to be a (necessary) focus call. Not sure this bug is actionable.
Presumably we could execute the focus call in a callback (rAF or promiseLayoutFlushed, or...) where we know layout isn't dirty and the reflow is essentially a no-op, assuming both focus + the selected tab hasn't changed in the meantime? This would make the focus change async though, and I don't know if that's likely to be acceptable. Mike, what do you think, given this is a tab switching issue?
Flags: needinfo?(mconley)
Comment 3•6 years ago
|
||
(In reply to :Gijs (he/him) from comment #2)
In my mind, the only way this would be unacceptable is if this results in a regression accessibility-wise, or if becomes possible for user events to be misdirected while we wait for the focus to occur. Otherwise, I think it'd be worth exploring.
Flags: needinfo?(mconley)
Updated•6 years ago
|
Whiteboard: [ohnoreflow][qf:p1][qf:f64][fxperf] → [ohnoreflow][qf:p1:f64][fxperf]
Assignee | ||
Updated•6 years ago
|
Whiteboard: [ohnoreflow][qf:p1:f64][fxperf] → [ohnoreflow][qf:p1:f64][fxperf:p3]
Comment 4•6 years ago
|
||
Re-queuing for triage by fxperf to reconcile with qf evaluation.
Whiteboard: [ohnoreflow][qf:p1:f64][fxperf:p3] → [ohnoreflow][qf:p1:f64][fxperf]
Comment 5•6 years ago
|
||
It seems like this shouldn't be too hard to do (unless it breaks a large number of tests), and since it looks like it happens fairly frequently I think it makes sense to promote this to p2, assuming there's no accessibility problems.
Whiteboard: [ohnoreflow][qf:p1:f64][fxperf] → [ohnoreflow][qf:p1:f64][fxperf:p2]
Updated•6 years ago
|
Assignee | ||
Comment 6•6 years ago
|
||
I'll look at this for a bit.
Assignee: nobody → gijskruitbosch+bugs
Status: NEW → ASSIGNED
Assignee | ||
Comment 7•6 years ago
|
||
Note that bug 1483354 comment 5 suggests making focus async might have unintended consequences.
Assignee | ||
Comment 8•6 years ago
|
||
I've just realized that I don't think we actually have good primitives to solve this.
In particular, even if we (*handwaves*) solve the issue with multiple async focus calls, we can't use promiseDocumentFlushed here.
The reason is that the "whole point" of pDF is that (a) we guarantee that the callback to that method gets fired on a clean (flushed) layout state, and (b) because there may be multiple such callbacks per flush, we can NEVER dirty layout state in the callback.
`.focus()` and/or `Services.focus.setFocus()` (apparently?) needs the layout state to be clean in order to not cause 'real' flushes, but will also dirty layout state because it changes the focused element, and the focused element can obviously be restyled based on that layout change.
So I guess the fundamental question here becomes: can we avoid `.focus()` dirtying layout state here? I assume we're flushing layout because we need to assess whether an element is focusable before directing focus to it. But the focusability of the URL bar / find bar / browser element doesn't actually change (much) here. Can't the focus manager just check if the element is focusable and only flush layout when it isn't? Or do we already do that?
Alternatively, how hard would it be to write a focus manager method that takes the same params and behaves like `.setFocus`, but essentially "promises" to focus that element on/after the next layout flush (without doing an additional flush), iff focus in the document does not change further before it gets a chance to do that?
Neil, do you know the answer to these questions?
Flags: needinfo?(enndeakin)
Assignee | ||
Comment 9•6 years ago
|
||
(In reply to :Gijs (he/him) from comment #8)
> So I guess the fundamental question here becomes: can we avoid `.focus()`
> dirtying layout state here?
Err, I meant: can we avoid `.focus()` flushing layout?
> I assume we're flushing layout because we need
> to assess whether an element is focusable before directing focus to it. But
> the focusability of the URL bar / find bar / browser element doesn't
> actually change (much) here. Can't the focus manager just check if the
> element is focusable and only flush layout when it isn't? Or do we already
> do that?
Comment 10•6 years ago
|
||
(In reply to :Gijs (he/him) from comment #9)
> (In reply to :Gijs (he/him) from comment #8)
> > So I guess the fundamental question here becomes: can we avoid `.focus()`
> > dirtying layout state here?
>
> Err, I meant: can we avoid `.focus()` flushing layout?
You may want to check out: bug 792297, bug 1369140, bug 1366250, bug 1371371
Assignee | ||
Updated•6 years ago
|
Assignee | ||
Comment 11•6 years ago
|
||
So based on comment #0, the exact stack here was hitting this
https://hg.mozilla.org/mozilla-central/annotate/a80de077d740/browser/base/content/tabbrowser.js#l1200
fm.setFocus(newBrowser, focusFlags);
call, which focuses the browser for the newly selected tab, after closing a tab. I don't seem to be able to reproduce that causing a layout flush, though I did find some STR for bug 1358813 which is essentially the same problem (but with an earlier .select() call triggered via focusAndSelectUrlBar)... so keeping the needinfo for now to try to figure out what's triggering these API calls sometimes still causing flushes.
Assignee | ||
Comment 12•6 years ago
|
||
(FWIW, if someone has STR to reproduce this specific reflow, that would be helpful, as I haven't been able to come up with any that worked for me.)
Updated•6 years ago
|
Flags: needinfo?(mconley)
Comment 13•6 years ago
|
||
> Err, I meant: can we avoid `.focus()` flushing layout?
If I remember, removing it causes test failures and compatibility issues.
You could always add a flag passed to SetFocus to avoid flushing in nsFocusManager::CheckIfFocusable for this case.
Flags: needinfo?(enndeakin)
Updated•6 years ago
|
Flags: needinfo?(mconley)
Assignee | ||
Comment 14•6 years ago
|
||
(In reply to Neil Deakin from comment #13)
> > Err, I meant: can we avoid `.focus()` flushing layout?
>
> If I remember, removing it causes test failures and compatibility issues.
>
> You could always add a flag passed to SetFocus to avoid flushing in
> nsFocusManager::CheckIfFocusable for this case.
Well, it seems like the extant code sometimes flushes and sometimes doesn't. I'm a little confused anyway, because looking in more detail, it seems the focus code should only ever flush frames/styles, and not flush layout. So it's not clear to me how we get to something that ohnoreflow reports from this setfocus code.
Assignee | ||
Comment 15•6 years ago
|
||
Per discussion with the fxperf folks, closing this for now while we don't have STR. If we have STR we can re-prioritize. I'll poke at bug 1358813 instead, given I have STR for that.
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → INCOMPLETE
Updated•3 years ago
|
Performance Impact: --- → P1
Whiteboard: [ohnoreflow][qf:p1:f64][fxperf:p2] → [ohnoreflow][fxperf:p2]
You need to log in
before you can comment on or make changes to this bug.
Description
•