Closing multiple tabs is slow because _setPositionalAttributes() is called for each tab
Categories
(Firefox :: Tabbed Browser, enhancement)
Tracking
()
People
(Reporter: Oriol, Assigned: Oriol)
References
(Blocks 1 open bug)
Details
(Keywords: perf:frontend)
Attachments
(2 files)
I had a window with a few tabs, like 5000. Still not too high, but I decided to close like 500, since otherwise lately I have started getting problems when doing session restore. Anyways, 500 is relatively small, but it took some time. That's not the first time that I have noticed this, so I recorded performance.
So, if I'm reading the graph correctly, most time is spend doing _setPositionalAttributes()
for every single tab. That's bad, I think that calling it once at the end would be enough.
STR:
-
Open a new window
-
Open the browser console, add 5000 tabs. We will not remove that many, but this is makes the problem more noticeable, since
_setPositionalAttributes()
takes more time when there are more tabs. Note that adding tabs is slow again because_setPositionalAttributes()
is called for each one of them, so do it in chunks:(async function() { const params = { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), createLazyBrowser: true, allowInheritPrincipal: true }; for (let chunk = 1; chunk <= 50; ++chunk) { const t = performance.now(); for (let i = 0; i < 100; ++i) gBrowser.addTab("about:blank", params); console.log(`Added chunk ${chunk}/50 of 100 tabs. It took ${performance.now() - t} ms`); await new Promise(r => setTimeout(r, 250)); } })();
-
Once all chunks are added and the window is responsive, we can run the test of removing the last 500 tabs:
(function() { const tabsToRemove = gBrowser.tabs.slice(-500); const t = performance.now(); gBrowser.removeTabs(tabsToRemove); console.log(`Removed the last ${tabsToRemove.length} tabs. It took ${performance.now() - t} ms`); })();
I'm getting values of 10-15 seconds. But if I comment out this line, then it's like 2 seconds, much better.
Assignee | ||
Comment 1•3 years ago
|
||
I was planning to make _setPositionalAttributes
wait a tick before doing the work, or abort if the work has already been scheduled. But bug 1760791 prevents this from working. Let's see if somebody can fix that, otherwise may have to use requestAnimationFrame
or similar but that seems more likely to break things.
Assignee | ||
Comment 2•3 years ago
|
||
Delaying with requestAnimationFrame
, this code
var params = { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), createLazyBrowser: true, allowInheritPrincipal: true };
var tabs = [];
var t = performance.now();
for (let i = 0; i < 2500; ++i)
tabs.push(gBrowser.addTab("about:blank", params));
gBrowser.removeTabs(tabs);
performance.now() - t;
improves from ~21 seconds to ~9 seconds, when the initially window has 1 tab. The improvement should be greater when the window already has lots of tabs.
Assignee | ||
Updated•3 years ago
|
Assignee | ||
Comment 3•3 years ago
|
||
Tried with requestAnimationFrame
, but then
./mach test browser/base/content/test/tabs/browser_positional_attributes.js --headless --repeat 10
fails various checks, even after adding a bunch of await new Promise(r => requestAnimationFrame(r));
.
It passes if I run it without repetitions, so using requestAnimationFrame
seems to introduce some flakiness.
Assignee | ||
Comment 4•2 years ago
|
||
On my system, this reduces the time needed to open and immediately close 2500
tabs, from ~20 seconds to ~10 seconds.
Awaiting requestAnimationFrame instead of a tick would probably make more sense,
and could optimize more cases, but seems more risky. It can be considered in a
follow-up.
Assignee | ||
Comment 5•2 years ago
|
||
(In reply to Oriol Brufau [:Oriol] from comment #1)
I was planning to make
_setPositionalAttributes
wait a tick before doing the work, or abort if the work has already been scheduled. But bug 1760791 prevents this from working. Let's see if somebody can fix that, otherwise may have to userequestAnimationFrame
or similar but that seems more likely to break things.
Waiting a tick seems to work now, even with gBrowser.removeTabs
calling Services.tm.spinEventLoopUntilOrQuit
. Maybe I was just affected by bug 1761590, or something else has changed.
Comment 6•1 years ago
|
||
Closing in favor of bug 1837174 which gets rid of _setPositionalAttributes
:)
Description
•