Open Bug 1417460 Opened 7 years ago Updated 7 months ago

Main thread rendering throbber animation for 5~6ms every 16ms while "idle"

Categories

(Core :: General, defect)

57 Branch
x86_64
Linux
defect

Tracking

()

People

(Reporter: SimonSapin, Unassigned)

Details

(Keywords: perf)

Sometimes, for no apparent reason and for several minutes at a time, Firefox’s main process uses a lot of CPU while nothing seems to be happening.

A profile shows Styles, DisplayList, and LayerBuilding markers every 16 ms in the main thread: https://perfht.ml/2huuIkc

Per IRC advice, I’ll try paint flashing next time this happens. Is there some other way to find out why this work happens in the first place?

This is Firefox 57.0 on Linux x86_64. Installed extensions are: Display #Anchors, Gecko Profiler, HTTPS Everywhere, Multi-Account Containers, Tree Style Tabs, and uBlock Origin.
Simon indicated in IRC that there were not any loading throbbers running.
Keywords: perf
At least none in the Tree Style Tabs sidebar. I had the tab bar hidden with #TabsToolbar { visibility: collapse !important; } in userChrome.css. I’ve disabled that for now until I can reproduce the issue.
Hey mstange - this reminds me of something we talked about a few weeks back... wasn't there a bug with panels on macOS where we'd continue to run the animation code for it after it had closed under certain circumstances? Or am I imagining?
Flags: needinfo?(mstange)
Ah, bug 1413763 was what I was thinking of (thanks Kwan!)

That sounds like it affects Windows only right now, so never mind.

I just took a look at the profile... I see this stack:

RestyleTracker::DoProcessRestyles moz-extension://e856f01f-2e0c-4e20-a869-2c5f835eb51f/sidebar/sidebar.html
mozilla::GeckoRestyleManager::ProcessPendingRestyles()
mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush)
PresShell::DoFlushPendingNotifications Style
nsRefreshDriver::Tick(long, mozilla::TimeStamp)
nsRefreshDriver::Tick
mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::ParentProcessVsyncNotifier::Run()
nsThread::ProcessNextEvent(bool, bool*)
NS_ProcessNextEvent(nsIThread*, bool)
mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*)
MessageLoop::Run()
nsBaseAppShell::Run()
nsAppStartup::Run()
XREMain::XRE_mainRun()
XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&)
XREMain::XRE_main
(root)

moz-extension://e856f01f-2e0c-4e20-a869-2c5f835eb51f/sidebar/sidebar.html

^-- that stands out to me. Do you have a WebExtension installed that's perhaps animating something in a sidebar?
Flags: needinfo?(mstange) → needinfo?(simon.sapin)
I have Tree Style Tabs in a sidebar, but I don’t think anything was visibly animated while this profile was taken.
Flags: needinfo?(simon.sapin)
(In reply to Simon Sapin (:SimonSapin) from comment #5)
> I have Tree Style Tabs in a sidebar, but I don’t think anything was visibly
> animated while this profile was taken.

Does disabling that add-on cause the issue to go away? Perhaps this is a bug in either our sidebar code, or in Tree Style Tabs itself.
Flags: needinfo?(simon.sapin)
As I mentioned, this situation happens semi-randomly a few times per day and I don’t know how to make it happen on demand. However it was happening again just now, and closing the sidebar (without disabling the extension) was enough made it stop.
Flags: needinfo?(simon.sapin)
Also, nothing was flashing with nglayout.debug.paint_flashing enabled.
In the Browser Toolbox, Performance, Waterfall, I see many Recalculate Style records with "Animation Only: true".

In the Inspector, I can pick random elements inside the sidebar and see that this particular element has no CSS animation. But I didn’t find how to get a list of all animations running in the sidebar or in the chrome.
(In reply to Simon Sapin (:SimonSapin) from comment #9)
> In the Browser Toolbox, Performance, Waterfall, I see many Recalculate Style
> records with "Animation Only: true".
> 
> In the Inspector, I can pick random elements inside the sidebar and see that
> this particular element has no CSS animation. But I didn’t find how to get a
> list of all animations running in the sidebar or in the chrome.

In the Console, does:

document.getElementById("sidebar").getAnimations()

return anything?
Flags: needinfo?(simon.sapin)
Component: Untriaged → General
Product: Firefox → Core
document.getElementById("sidebar").getAnimations() returns an empty array. document.getElementById("sidebar").contentDocument.getElementById("webext-panels-browser").contentDocument.getAnimations() returns an array of length 1. The object inside has animationName: "throbber".

I believe this is the CSS @keyframes animation defined at https://github.com/piroor/treestyletab/blob/2.2.7/webextensions/sidebar/styles/throbber.css and used with this selector:

.tab.loading:not(.collapsed) .throbber::before,
:root.blocking-throbber #blocking-screen .throbber::before

However no throbber is visible at the moment, and document.getElementById("sidebar").contentDocument.getElementById("webext-panels-browser").querySelectorAll(".loading") returns an empty NodeList.
Flags: needinfo?(simon.sapin)
Huh. Interesting.

Hey TheOne, are we able to point the TreeStyleTabs WebExtension author at this? Perhaps they can help us figure out what this throbber is up to, and whether or not we've got an engine bug here.
Flags: needinfo?(awagner)
This code seems relevant:

https://github.com/piroor/treestyletab/blob/2.2.7/webextensions/sidebar/sidebar.js#L745-L757

    async function synchronizeThrobberAnimations() {
      var throbbers = getVisibleLoadingTabs().map(getTabThrobber);
      var animations = [];
      for (let throbber of throbbers) {
        if (typeof throbber.getAnimations == 'function') // sometimes non-animated throbber can appear in the result
          animations = animations.concat(throbber.getAnimations({ subtree: true }));
      }
      var firstStartTime = Math.min(...animations.map(aAnimation => aAnimation.startTime));
      await nextFrame();
      for (let animation of animations) {
        animation.startTime = firstStartTime;
      }
    }

It sets the startTime property of some Animation objects. Could that cause the animation to keep running after a selector stops matching and the 'animation' property is reset to its initial value?
Adding Piro, the author of TST.
Flags: needinfo?(awagner) → needinfo?(yuki)
Even if the extension does this, do we really need to do the rendering work if the element is non-visible?
(In reply to Simon Sapin (:SimonSapin) from comment #13)
> This code seems relevant:

This synchronization logic is based on the idea same to the one for Firefox's native tab bar. See also:
https://dxr.mozilla.org/mozilla-central/rev/a3f183201f7f183c263d554bfb15fbf0b0ed2ea4/browser/base/content/tabbrowser.xml#616

My version was a subset of this, and there was some missing part. So I've import more codes to ignore needless animations:
https://github.com/piroor/treestyletab/commit/81fa73e0128f4831fd1a6d453d1b5d653adabd88

Here is a development build based on master, HEAD:
https://piro.sakura.ne.jp/xul/xpi/nightly/treestyletab-we.xpi

Does the change affect to this problem?
Flags: needinfo?(yuki)
Summary: Main thread rendering stuff for 5~6ms every 16ms while "idle" → Main thread rendering throbber animation for 5~6ms every 16ms while "idle"
Severity: normal → S3

(In reply to YUKI "Piro" Hiroshi from comment #16)

(In reply to Simon Sapin (:SimonSapin) from comment #13)

This code seems relevant

My version was a subset of this, and there was some missing part. So I've
import more codes to ignore needless animations:
https://github.com/piroor/treestyletab/commit/
81fa73e0128f4831fd1a6d453d1b5d653adabd88
...

Does the change affect to this problem?

Simon, is the problem gone, or better with newer versions?

(I also use TST)

Flags: needinfo?(simon.sapin)

Clear a needinfo that is pending on an inactive user.

Inactive users most likely will not respond; if the missing information is essential and cannot be collected another way, the bug maybe should be closed as INCOMPLETE.

For more information, please visit BugBot documentation.

Flags: needinfo?(simon.sapin)
You need to log in before you can comment on or make changes to this bug.