Loading recent DOOM files on wadcmd.com takes ~40s on Firefox, ~2s in Chrome
Categories
(Core :: Layout, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox102 | --- | verified |
People
(Reporter: mcomella, Assigned: emilio)
References
Details
Attachments
(4 files)
Basic information
Steps to Reproduce:
- Visit wadcmd.com (it's a website that runs the DOOM game in WASM)
- Note: Doom game assets are stored in ".wad" files. I used the ".wad" file associated with the purchasable game but you can presumably reproduce this with the free shareware files linked from the site
- Click "doom.wad" in Recent files (note: it caches files you've previously opened. For convenience I used this functionality but you might be able to reproduce through the "Open file(s)" link selector instead)
Expected Results:
Firefox and Chrome load times are roughly comparable
Actual Results:
Firefox takes ~40s while Chrome takes ~2s. Curiously, Firefox does not seem to be maxing out the CPU and the file it's probably loading is only a few MiB so it seems weird to take so long.
Note: I've played this for a bit in Chrome but haven't in Firefox – maybe things are better cached?
More information
Screenshot: (if relevant, please attach a screenshot or screencast to this bug report)
Profile URL: (follow the instructions at https://profiler.firefox.com/)
- Firefox: https://share.firefox.dev/3A4IGzE
- Chrome (attached)
Basic systems configuration:
OS version: macOS 11.5.2
GPU model: AMD Radeon Pro 5300M 4 GB
Intel UHD Graphics 630 1536 MB
Number of cores: 8
Amount of memory (RAM): 64 GB
Thanks so much for your help.
| Reporter | ||
Updated•4 years ago
|
Updated•4 years ago
|
Updated•3 years ago
|
Comment 1•3 years ago
|
||
Clicking Phase 1 for example does show the difference. Not much CPU is used when initializing the game.
I get similar profile locally as in comment 0. Child process is almost empty but it does get vsync.
The issues seems to be about throttling hidden iframes. If I change layout.throttled_frame_rate to 60, loading happens very fast.
Comment 2•3 years ago
|
||
We probably shouldn't throttle hidden iframes if they have explicit rAF callbacks registered.
Comment 3•3 years ago
|
||
The severity field is not set for this bug.
:emilio, could you have a look please?
For more information, please visit auto_nag documentation.
| Assignee | ||
Comment 4•3 years ago
|
||
I don't know how to reproduce this, but Olli, since you could, can you check that changing layout.oopif_activity_grace_period_ms to something large also fixes it?
Comment 5•3 years ago
|
||
layout.oopif_activity_grace_period_ms doesn't help here. I tried with value 60000.
layout.throttled_frame_rate 60 does help.
Surprising if you can't reproduce. Just clicking "Phase 1" link in the page should do it.
Comment 6•3 years ago
|
||
The severity field is not set for this bug.
:emilio, could you have a look please?
For more information, please visit auto_nag documentation.
| Assignee | ||
Comment 7•3 years ago
•
|
||
Ah, d'oh, I didn't realize there were premade files, I just saw the big blue button.
So the relevant iframe is styled like this:
#inspect {
position: fixed;
top: 0;
right: 0;
width: 0;
height: 0;
border: none;
}
And is same-origin. Just using width: 1px; height: 1px; or so makes it fast... So we're hitting this code-path: https://searchfox.org/mozilla-central/rev/88792eff309001778cb2431f2a0ed92f8f3c258a/dom/base/Document.cpp#7064
So... This code comes from bug 1145439.
| Assignee | ||
Comment 8•3 years ago
|
||
Olli, seems like Chrome doesn't throttle RAF at all for the foreground tab. Thoughts on whether we should just do that?
Comment 9•3 years ago
|
||
Not throttling would be at least less surprising for the web devs. I wonder why we started to throttle.
| Assignee | ||
Comment 10•3 years ago
|
||
So, same-origin-test-case would be comment 8 or https://crisal.io/tmp/raf-throttle.html
Cross-origin test-case would be http://crisal.io/tmp/raf-throttle.html
It seems Chrome throttles display: none cross-origin iframes by a factor of three, and completely stops offscreen cross-origin iframes (which doesn't make all that much sense to me?).
| Assignee | ||
Comment 11•3 years ago
|
||
Safari seems to throttle offscreen iframes unconditionally, and Chrome canary does seem to throttle display: none cross-origin iframes. So this is a bit messy
Comment 12•3 years ago
|
||
The severity field is not set for this bug.
:dholbert, could you have a look please?
For more information, please visit auto_nag documentation.
| Assignee | ||
Comment 13•3 years ago
|
||
I think I have a reasonably good idea to fix this.
| Assignee | ||
Comment 14•3 years ago
|
||
| Assignee | ||
Comment 15•3 years ago
|
||
This is more likely to be understandable by developers, matches other
browsers more closely (see bug comments), and seems more in-line with
what we do for OOP iframes.
Add a pref to not do this throttling at all (which would match Chrome),
though this is probably good enough for now.
Depends on D146573
| Reporter | ||
Comment 16•3 years ago
|
||
Florian, do you have any concerns with how changing the throttling behavior could affect power usage?
Emilio, it may help if you could summarize how your change could affect power usage so Florian doesn't need to dig too deep.
| Assignee | ||
Comment 17•3 years ago
•
|
||
See comment 10+ for an analysis. The tldr is that we now throttle and would stop throttling 0-sized and visibility: hidden / opacity: 0 same-origin iframes. Behavior otherwise should be mostly unchanged, and other browsers don't seem to throttle these.
Comment 18•3 years ago
|
||
Comment 19•3 years ago
|
||
Backed out 2 changesets (Bug 1730284) for causing devtools,web-platform and mochitest failures CLOSED TREE
Log: https://treeherder.mozilla.org/logviewer?job_id=379282305&repo=autoland&lineNumber=4367
https://treeherder.mozilla.org/logviewer?job_id=379282683&repo=autoland&lineNumber=5607
https://treeherder.mozilla.org/logviewer?job_id=379284333&repo=autoland&lineNumber=5092
Backout: https://hg.mozilla.org/integration/autoland/rev/b913035865bcceaf618de9b21c66e6b04bd6634e
| Assignee | ||
Updated•3 years ago
|
Comment 20•3 years ago
|
||
| Assignee | ||
Updated•3 years ago
|
Comment 21•3 years ago
|
||
| bugherder | ||
| Assignee | ||
Comment 22•3 years ago
|
||
Ok so the devtools tests I got figured out. Boris, it seems we're asserting rather frequently in scroll-animations/css/at-scroll-timeline-dynamic.tentative.html after my change, and I'm pretty sure it's not a bug in my code.
The assert is this:
MOZ_ASSERT(timeline->IsMonotonicallyIncreasing(),
"Don't put non-MonotoniciallyIncreasing timeline into "
"PendingAnimationTracker");
We end up there because the test creates a regular CSS animation which is added to the pending animation tracker here:
(rr) bt
#11 mozilla::PendingAnimationTracker::AddPending(mozilla::dom::Animation&, nsTBaseHashSet<nsRefPtrHashKey<mozilla::dom::Animation> >&) (this=0x7f9b1558ee40, aAnimation=..., aSet=...)
at /home/emilio/src/moz/gecko-6/dom/animation/PendingAnimationTracker.cpp:31
#12 mozilla::PendingAnimationTracker::AddPlayPending(mozilla::dom::Animation&) (this=0x7f9b1558ee40, aAnimation=...)
at /home/emilio/src/moz/gecko-6/dom/animation/PendingAnimationTracker.h:39
#13 0x00007f9b1f1868ee in mozilla::dom::Animation::PlayNoUpdate(mozilla::ErrorResult&, mozilla::dom::Animation::LimitBehavior)
(this=this@entry=0x7f9b155e5500, aRv=..., aLimitBehavior=aLimitBehavior@entry=mozilla::dom::Animation::LimitBehavior::Continue) at /home/emilio/src/moz/gecko-6/dom/animation/Animation.cpp:1448
#14 0x00007f9b1f18d515 in mozilla::dom::Animation::Play(mozilla::ErrorResult&, mozilla::dom::Animation::LimitBehavior) (this=0x7f9b155e5500, aRv=..., aLimitBehavior=mozilla::dom::Animation::LimitBehavior::Continue)
at /home/emilio/src/moz/gecko-6/dom/animation/Animation.cpp:639
#15 mozilla::dom::CSSAnimation::PlayFromStyle() (this=0x7f9b155e5500)
at /home/emilio/src/moz/gecko-6/dom/animation/CSSAnimation.cpp:104
#16 0x00007f9b2182162e in BuildAnimation(nsPresContext*, mozilla::NonOwningAnimationTarget const&, nsStyleUIReset const&, unsigned int, ServoCSSAnimationBuilder&, mozilla::AnimationCollection<mozilla::dom::CSSAnimation>*)
But then gets its timeline updated in a subsequent restyle but without removing from the pending animation tracker:
(rr) bt
#0 RefPtr<mozilla::dom::AnimationTimeline>::assign_assuming_AddRef(mozilla::dom::AnimationTimeline*)
(this=0x7f9b155e5590, aNewPtr=0x7f9b15544a60)
at /home/emilio/src/moz/gecko-6/obj-debug/dist/include/mozilla/RefPtr.h:68
#1 RefPtr<mozilla::dom::AnimationTimeline>::assign_with_AddRef(mozilla::dom::AnimationTimeline*)
(this=0x7f9b155e5590, aRawPtr=0x7f9b15544a60)
at /home/emilio/src/moz/gecko-6/obj-debug/dist/include/mozilla/RefPtr.h:62
#2 RefPtr<mozilla::dom::AnimationTimeline>::operator=(mozilla::dom::AnimationTimeline*)
(this=0x7f9b155e5590, aRhs=0x7f9b15544a60)
at /home/emilio/src/moz/gecko-6/obj-debug/dist/include/mozilla/RefPtr.h:190
#3 mozilla::dom::Animation::SetTimelineNoUpdate(mozilla::dom::AnimationTimeline*)
(this=0x7f9b155e5500, aTimeline=0x7f9b15544a60) at /home/emilio/src/moz/gecko-6/dom/animation/Animation.cpp:257
#4 0x00007f9b218215aa in UpdateOldAnimationPropertiesWithNew(mozilla::dom::CSSAnimation&, mozilla::TimingParams&&, nsTArray<mozilla::Keyframe>&&, bool, mozilla::CSSAnimationProperties, ServoCSSAnimationBuilder&, mozilla::dom::AnimationTimeline*)
(aOld=..., aNewTiming=..., aNewKeyframes=nsTArray<mozilla::Keyframe> && = {...}, aOverriddenProperties=mozilla::CSSAnimationProperties::None, aBuilder=..., aTimeline=0x7f9b15544a60, aNewIsStylePaused=<optimized out>)
at /home/emilio/src/moz/gecko-6/layout/style/nsAnimationManager.cpp:182
#5 BuildAnimation(nsPresContext*, mozilla::NonOwningAnimationTarget const&, nsStyleUIReset const&, unsigned int, ServoCSSAnimationBuilder&, mozilla::AnimationCollection<mozilla::dom::CSSAnimation>*)
(aPresContext=0x7f9b15541400, aTarget=..., aStyle=..., animIdx=0, aBuilder=..., aCollection=0x7f9b15572e00)
at /home/emilio/src/moz/gecko-6/layout/style/nsAnimationManager.cpp:286
#6 BuildAnimations(nsPresContext*, mozilla::NonOwningAnimationTarget const&, nsStyleUIReset const&, ServoCSSAnimationBuilder&, mozilla::AnimationCollection<mozilla::dom::CSSAnimation>*, nsTBaseHashSet<nsRefPtrHashKey<nsAtom> >&)
(aPresContext=0x7f9b15541400, aTarget=..., aStyle=..., aBuilder=..., aCollection=0x7f9b15572e00, aReferencedAnimations=...) at /home/emilio/src/moz/gecko-6/layout/style/nsAnimationManager.cpp:338
#7 nsAnimationManager::DoUpdateAnimations(mozilla::NonOwningAnimationTarget const&, nsStyleUIReset const&, ServoCSSAnimationBuilder&) (this=0x7f9b15596bf0, aTarget=..., aStyle=..., aBuilder=...)
at /home/emilio/src/moz/gecko-6/layout/style/nsAnimationManager.cpp:398
#8 0x00007f9b21820c10 in nsAnimationManager::UpdateAnimations(mozilla::dom::Element*, mozilla::PseudoStyleType, mozilla::ComputedStyle const*)
(this=0x7f9b155c87c0, aElement=<optimized out>, aPseudoType=<optimized out>, aComputedStyle=<optimized out>)
at /home/emilio/src/moz/gecko-6/layout/style/nsAnimationManager.cpp:374
#9 0x00007f9b217e9b60 in Gecko_UpdateAnimations(mozilla::dom::Element const*, mozilla::ComputedStyle const*, mozilla::ComputedStyle const*, mozilla::UpdateAnimationsTasks)
(aElement=0x1, aOldComputedData=0x0, aComputedData=0x7f9b155e44c8, aTasks=(mozilla::UpdateAnimationsTasks::CSSAnimations | mozilla::UpdateAnimationsTasks::EffectProperties | mozilla::UpdateAnimationsTasks::CascadeResults))
at /home/emilio/src/moz/gecko-6/layout/style/GeckoBindings.cpp:522
#10 0x00007f9b254bc533 in style::gecko::wrapper::{impl#16}::update_animations
Boris do you know what the best way to deal with this is? Should we be removing from the pending tracker or just turn the assertion into an early return or something?
Comment 23•3 years ago
|
||
Comment 24•3 years ago
|
||
Comment 25•3 years ago
|
||
Comment 26•3 years ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #22)
Ok so the devtools tests I got figured out. Boris, it seems we're asserting rather frequently in
scroll-animations/css/at-scroll-timeline-dynamic.tentative.htmlafter my change, and I'm pretty sure it's not a bug in my code.The assert is this:
MOZ_ASSERT(timeline->IsMonotonicallyIncreasing(), "Don't put non-MonotoniciallyIncreasing timeline into " "PendingAnimationTracker"); Boris do you know what the best way to deal with this is? Should we be removing from the pending tracker or just turn the assertion into an early return or something?
This is our missing part. I think we could just remove the scroll-timeline animations from pending animation tracker when setting a new timeline if the new timeline is scroll-timeline and old timeline is document timeline. We play the scroll-timeline animations directly without touching pending animation tracker (which is only for document-timeline animations). In this test case, we switch between document-timeline and scroll-timeline, and obviously we forgot to remove it from pending animation tracker.
Note: animation-timeline: auto uses document-timeline, and animation-timeline: <custom-ident> uses scroll-timeline if we define it somewhere.
Comment 27•3 years ago
|
||
| bugherder | ||
| Assignee | ||
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
Updated•3 years ago
|
I managed to reproduce this bug on a 2021-09-10 Nightly build on macOS 11 using the free shareware files linked from the site; verified as fixed on Firefox 102.0b8(20220614185842) and Nightly 103.0a1(20220614213729) on macOS 11, Windows 10 x64 and Ubuntu 20.04.
Updated•2 years ago
|
Description
•