Open Bug 1809608 Opened 3 years ago Updated 2 years ago

specific page leads to 100% cpu with webrender software

Categories

(Core :: Graphics: WebRender, defect)

Firefox 110
defect

Tracking

()

UNCONFIRMED
Performance Impact low

People

(Reporter: linuxhippy, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: perf:pageload, perf:responsiveness)

Attachments

(3 files)

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/110.0

Steps to reproduce:

  1. I am using firefox in VirtualBox -> WebRender software is automatically enabled
  2. opened https://www.akkudoktor.net/forum/akku-tests/test-wulills-12v-200ah-billig-akku-aus-china/paged/2/
  3. scrolled to bottom

Actual results:

firefox uses 70-100% cpu constantly and is hardly responsive anymore, please see the attached profile

Expected results:

firefox should render the page smoothly, despite using software rendering

The Bugbug bot thinks this bug should belong to the 'Core::Graphics: WebRender' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Graphics: WebRender
Product: Firefox → Core

This is what I get on a Win11x64 machine: https://share.firefox.dev/3W6Xjg2

There's a transform animation in #wpforo-load .fa-spin that is under a visibility: hidden element so ends up being a no-op... Does removing that help?

Blocks: gfx-triage

Shared URL of the attached profile is https://share.firefox.dev/3vWlhA2

Blocks: wr-perf
No longer blocks: gfx-triage
Severity: -- → S3
Flags: needinfo?(ahale)
Summary: sepcific page leads to 100% cpu with webrender software → specific page leads to 100% cpu with webrender software
Attached image akkudoktor.jpg

I attached an screenshot of the element which causes the cpu spike and as you suspected it is the animated div with an invisible parent.
as far as I understand that should be a no-op, but maybe there are some corner-cases which cause this element to trigger re-rendering to be conformant to spec? what makes me wonder too, is how such a small region can cause two virtual cores to go to 100% - i thought webrender now supports partial re-rendering of page regions?

just tested - chromium with the same page doesn't consume (a lot of) CPU when the page is just open with no further interaction.
So it seems to be possible to avoid rendering that animation, or rendering is just a lot faster with chromium.

I'm not really sure how the visibility hidden flag is not suppressing the stacking contexts, I agree it shouldn't have this kind of impact even if it was visible.

NI - do we have an idea how this can happen or how I should go about debugging it?

Flags: needinfo?(ahale) → needinfo?(gwatson)

Emilio - thoughts on what we should be doing with this? From a quick scan of it, it sounds like ideally Gecko should not be supplying new display lists and requesting frames in this case, but perhaps that's much harder than it sounds to do?

Flags: needinfo?(gwatson) → needinfo?(emilio)

Yeah, we have code to throttle animations in visibility: hidden subtrees. Hiro, do you happen to have cycles to poke at this? If not please ni? me back and I can dig.

Flags: needinfo?(emilio) → needinfo?(hikezoe.birchill)

So, I saw a bunch of Render reason ASYNC IMAGE IIRC the profile result, I think the animation in question in the visibility:hidden subtree is animated GIF?

Flags: needinfo?(hikezoe.birchill)
Attached file Reduced test-case.

No, it's a spinning icon, which shows up in the animation inspector. Here's a reduced test-case that seems to reproduce this.

Flags: needinfo?(hikezoe.birchill)

I am confused. As far as I can tell the animation in question is properly optimized by this CanThrottleIfNotVisible check. (I did double check both on the reduced test case in comment 12 and the original site).

https://share.firefox.dev/3Zk3grQ is a profile result took on the reduced test case, I don't see it's hogging CPU.

Keep NI to me. I will take a look at the original case.

Okay, this is kinda involving the throttled animation actually, but...

The site does invoke window.scrollY in a requestAnimationFrame callback repeatedly, then if the scroll position isn't (0, 0) we do forcibly flush any pending styles including the animation one of course, it ends up WebRender's scene building repeatedly, it hogs CPU.

So I guess, even if there's forcibly flushed animation styles but if the result of display items (and other related objects) were unchanged, WebRender can skip scene buildings? I am totally unsure but there's nothing we can do for this case in animation stuff as far as I can tell.

There looks also an opportunity where we flush pending styles in nsGlobalWindowOuter::GetScrollXY, if the scroll position has been unchanged since the last flush, we don't need to flush pending styles I guess? (I am not sure why the flush was necessary there)

(Note that the animation isn't generated if the system's prefers reduced motion setting is true.)

Flags: needinfo?(hikezoe.birchill)

(In reply to Hiroyuki Ikezoe (:hiro) from comment #14)

There looks also an opportunity where we flush pending styles in nsGlobalWindowOuter::GetScrollXY, if the scroll position has been unchanged since the last flush, we don't need to flush pending styles I guess? (I am not sure why the flush was necessary there)

Okay there's a description about this "the content may get shorter and hence our scroll position may decrease". :)

Performance Impact: --- → ?

The Performance Impact Calculator has determined this bug's performance impact to be low. If you'd like to request re-triage, you can reset the Performance Impact flag to "?" or needinfo the triage sheriff.

Impact on browser: Causes noticeable jank
Impact on site: Causes noticeable jank
Page load impact: Severe
Websites affected: Rare

Performance Impact: ? → low
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: