Open Bug 1750463 Opened 3 years ago Updated 3 years ago

"This page is slowing down your browser" notifications cause resize events, which can hang slow-to-layout pages even more

Categories

(Core :: Performance, defect, P3)

Firefox 98
defect

Tracking

()

Performance Impact low

People

(Reporter: u693231, Unassigned)

References

()

Details

(Keywords: perf:responsiveness)

Attachments

(1 file)

Steps to reproduce:

Visit https://data.firefox.com/dashboard/hardware
Zoom to 120%

Actual results:

Got "this page is slowing down your computer" message, and very slow reflow.

Expected results:

No "this page is slowing down your computer" message, faster reflow.

It seems to take chrome about 30 seconds to resize this page on my machine

Has STR: --- → yes
Component: Untriaged → Performance
Product: Firefox → Core

Grabbed a profile - https://share.firefox.dev/3rrFKtQ

I increased the page zoom twice and scrolled the page.

Status: UNCONFIRMED → NEW
Component: Performance → Graphics
Ever confirmed: true

This seems to be spending all its time in SVG code -- in particular, SVGGeometryElement::GetPointAtLength -- so moving to that component. Maybe there's some caching opportunity that we're missing, with the result that we re-evaluate all the long paths on the page too many times?

Component: Graphics → SVG

The severity field is not set for this bug.
:dholbert, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(dholbert)

I'm seeing similarly-bad performance in Chrome, FWIW (over ten seconds of delay between Ctrl+ and an actual visible increase in zoom level, which is about how long I have to wait in Firefox as well).

So this seems likely to just be pathological content...

Flags: needinfo?(dholbert)

Here's a profile of me doing a "Ctrl +" operation in Chrome: https://share.firefox.dev/3rePWHa

Hmm, we might be hitting an extra-bad outcome here, from the fact that
(a) I think this page triggers this slow-behavior on viewport resizes
(b) The "This page is slowing down your browser" notification looks like it causes the viewport to resize...

Here's a profile of me doing a "Ctrl +" operation in Firefox: https://share.firefox.dev/3s90Ugy

Notice:
(1) We seem to finish the work (and redraw at a higher zoom level) in about 13 seconds
(2) ...but then a DOM resize event gets fired (presumably in response to the slow-page notification that appeared and shrunk the viewport)
(3) ...and then after we spend another ~13 seconds doing the same work again, we get another DOM resize event (maybe from the same notification having disappeared, which grows the viewport a bit and perhaps caused this resize to get queued up?)
(4) ...and then after we process that one, finally we're done, though I could imagine this continuing to ping-pong indefinitely perhaps.

Here's a profile of me doing a Ctrl + operation in Firefox after I've increased about:config setting dom.max_script_run_time to 40 (and restarting Firefox for good measure, though I'm not sure that's necessary): https://share.firefox.dev/3Hlbyrg

Notably, we just have one ~10 second period of jank, without any "chained" resize events, and then we're done.

That confirms that this bug is an unfortunate downstream effect of the fact that the slow-page notification causes the viewport to resize, and this page does ~10 seconds of work in response to the viewport being resized (or the zoom level changing which is what kicks things off in the STR here).

Given that Chrome does even-more work in response to a single zoom/resize operation (they take ~16 seconds rather than ~13 seconds), it seems unlikely that there's a Firefox-specific SVG bug under the covers here. What we do have is:
(1) some issues with https://data.firefox.com/ being needlessly-painful to resize (which we presumably can fix since that's our site)
(2) this ping-pong issue with the slow-page notification.

Issue #2 is probably the more-concerning thing since it could be affecting lots of sites for all we know. --> Reclassifying this bug under Performance since I think they own that notification.

Component: SVG → Performance
Summary: data.firefox.com takes 1-2 minutes to reflow zoom → data.firefox.com takes 1-2 minutes to reflow zoom (due to daisy-chained "this page is slowing down your browser" notifications, which cause resize events, which cause more batches of work for the page, which cause more notifications etc)

I filed https://github.com/mozilla/ensemble/issues/409 on the site itself being slow here. (I think that's where this data.firefox.com visualization is managed? https://data.firefox.com/ lists "...the projects that power it" at the bottom, which include "ensemble (data visualization)". Unfortunately the last commit there was ~2 years ago, so I'm not sure it's actively maintained at this point.)

In any case: now we can focus this bug here on the underlying issue of the ping-pong-potential between the slow-script notification and slow resize handlers, as illustrated by my just-attached testcase.

STR using the attached testcase:

  1. Load the testcase: https://bugzilla.mozilla.org/attachment.cgi?id=9261605
  2. Click the button.
  3. At some point during the following 10 seconds, press a key (e.g. Ctrl), or mousewheel-scroll the page.
  4. Wait until the "0 batches of slow stuff" text changes to show "1", and then see if you can interact with the page (e.g. select text) at that point.

EXPECTED RESULTS:

  • The page shouldn't report any more than 1 batch of slow stuff having occurred.
  • The page should be interactive (I should be able to select text etc.) after that batch has completed (after "1" shows up).

ACTUAL RESULTS:

  • The page ends up reporting that 2 (or more) batches of slow stuff occurred. (Each time you interact with the page during doSlowStuff, it ensures that a "page is slowing down" notification will appear, which will trigger a resize event which will trigger another batch of the page's doSlowStuff JS.)
  • You can't reliably interact with the page (select text, etc.) as long as this ping-ponging keeps up (which is potentially forever, if you keep trying to interact).

dthayer, I think you worked on the slow-script notification -- do you know if this is a known issue?

Flags: needinfo?(dothayer)

Hmm - yeah this is not a known issue. I suppose we could do two things here:

  • We could have the slow script notification just overlay the content. That's what Chrome's does, although it's a modal instead of a notification bar. This is using a shared notification system, so we'd have to sort out whether we want to do this for all notifications or just the slow script one. Anyway, I'm not opposed to doing that, though I could see it annoying some users for reasons that I can't think of right now.
  • We could suppress the viewport size change, knowing that the page can't meaningfully respond to it anyway while it is blocked. I'm more in favor of this change - as it should behave basically identically with how it currently does, just without potential for exacerbating the problem.
Flags: needinfo?(dothayer)

(In reply to Doug Thayer [:dthayer] (he/him) from comment #12)

  • We could suppress the viewport size change, knowing that the page can't meaningfully respond to it anyway while it is blocked. I'm more in favor of this change - as it should behave basically identically with how it currently does, just without potential for exacerbating the problem.

This is tempting, but I'm not sure we could actually do it robustly...

We could e.g. fix the attached pathological testcase by specifically suppressing the resize event on the top-level document, but:
(1) there are other ways that pages could inadvertently be watching for viewport-resizes that we'd also have to suppress in order to make this robust (e.g. the page might have a ResizeObserver, or the page could conceivably have a full-viewport-sized iframe and that iframe's inner document might have an onresize handler which would still fire because the iframe would legitimately be changing size).

(2) if there are multiple things causing a viewport-resize at the same time that the slow-script dialog is appearing (e.g. maybe the user opens devtools or resizes their browser window at the same time), we would need to be sure that we do still dispatch the resize event so that the page can react to the new viewport-size (if it needs to) once it's done with its slow stuff.

It feels pretty-hard to have the slow-script notification visually shrink the viewport while still being reliably undetectable (and having no chance of kicking off more slow scripts).... So I tend to think we need to have it overlay the viewport somehow instead of shrinking it.

With notification bars at the top, you fundamentally have the choice between 1. resizing the viewport (what we do at the moment), 2. covering up some content, or 3. doing something sophisticated with a lot of magic. We have gathered some experience with 3 in the various incarnations of the dynamic toolbar of Firefox on Android, but we've never had something that works on Desktop. An ideal solution for all notification bars at the top (or find bars at the top) would (a) Not shift the page content, even on non-scrollable pages, (b) shift down position:fixed elements without reflow for elements which are anchored to the top, (c) make the covered-up content at the top accessible by scrolling, and (d) not change the layout viewport or affect the vh unit. See also bug 893446 where we tried to fix (a) partially for findbar-at-the-top, only to find out that it wasn't good enough, so findbar-at-the-top was backed out again.

However, maybe there is indeed a simpler solution that works specifically for the slow script notification bar.

(In reply to Daniel Holbert [:dholbert] from comment #13)

(In reply to Doug Thayer [:dthayer] (he/him) from comment #12)

  • We could suppress the viewport size change, knowing that the page can't meaningfully respond to it anyway while it is blocked. I'm more in favor of this change - as it should behave basically identically with how it currently does, just without potential for exacerbating the problem.

This is tempting, but I'm not sure we could actually do it robustly...

We could e.g. fix the attached pathological testcase by specifically suppressing the resize event on the top-level document, but:
(1) there are other ways that pages could inadvertently be watching for viewport-resizes that we'd also have to suppress in order to make this robust (e.g. the page might have a ResizeObserver, or the page could conceivably have a full-viewport-sized iframe and that iframe's inner document might have an onresize handler which would still fire because the iframe would legitimately be changing size).

(2) if there are multiple things causing a viewport-resize at the same time that the slow-script dialog is appearing (e.g. maybe the user opens devtools or resizes their browser window at the same time), we would need to be sure that we do still dispatch the resize event so that the page can react to the new viewport-size (if it needs to) once it's done with its slow stuff.

It feels pretty-hard to have the slow-script notification visually shrink the viewport while still being reliably undetectable (and having no chance of kicking off more slow scripts).... So I tend to think we need to have it overlay the viewport somehow instead of shrinking it.

I don't mean suppressing the event, but rather the resizing itself. Effectively just shifting the <browser> element down off screen and clipping it out while the notification is displayed.

(In reply to Markus Stange [:mstange] from comment #14)

With notification bars at the top, you fundamentally have the choice between 1. resizing the viewport (what we do at the moment), 2. covering up some content

Yes, but today we're really doing both 1 and 2, because the content can't even actually respond to the viewport resize. So I was suggesting that we commit to 2 on the bottom, since we're taking that hit anyway.

(In reply to Doug Thayer [:dthayer] (he/him) from comment #16)

I don't mean suppressing the event, but rather the resizing itself. Effectively just shifting the <browser> element down off screen and clipping it out while the notification is displayed.

Right, so as you note, this is a fancy version of Markus's "Option 2" (covering up some content -- except that the covered-up content is at the opposite end of the viewport from where the notification appears).

Usability/cosmetic drawbacks that come to mind:

  • It would look pretty broken on any page with a scrollbar, on a platform with scrollbuttons (e.g. Win10), since the bottom scroll-button would just get pushed out of view and be clipped outside of the Firefox window for no clear reason, leaving an unbalanced scroll-track with an uparrow at the top and a clipped/truncated track at the bottom.
  • If the user is focused on the page content & doesn't immediately notice our top-notification, they may get confused as to why a site's bottom-aligned controls (e.g. their Matrix/Slack text-entry box, their Spotify song-progress-scrubber, the bottom row of their Wordle keyboard) have suddenly disappeared. As they go searching along the bottom of their screen to find where this important UI has gone missing, they may miss or not understand our notification which is patiently waiting for them at the opposite end of the screen.

For both of these bullet-points, it feels possibly better/more-graceful for the the notification to just slide down & overlap the content on top, because then it's clearer why some content (whether page controls or a scroll-button) disappeared, and how the user can get to it -- it's clearly "underneath" the notification, and will reappear if you dismiss the notification.

Setting performance priority P3 on this: Most pages which show the slow script notification bar do so due to slow JS and not due to slow layout. And the viewport resize causes one or two extra reflows, but not more - even with the bar animating in, we only ever reflow to the "latest known" size in the content process. The profile from comment 7 shows three reflows in total.

Severity: -- → S3
Performance Impact: --- → P3
Priority: -- → P3
Summary: data.firefox.com takes 1-2 minutes to reflow zoom (due to daisy-chained "this page is slowing down your browser" notifications, which cause resize events, which cause more batches of work for the page, which cause more notifications etc) → "This page is slowing down your browser" notifications cause resize events, which can hang slow-to-layout pages even more
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: