Closed Bug 2068549 Opened 12 days ago Closed 11 days ago

Content in a new remote browser can load and fire load with a 0x0 viewport

Categories

(Core :: DOM: Core & HTML, defect)

defect

Tracking

()

RESOLVED FIXED
157 Branch
Tracking Status
firefox157 --- fixed

People

(Reporter: florian, Assigned: emilio)

References

Details

Attachments

(1 file)

A newly created remote <browser> has no viewport size until the parent process reflows it and sends PBrowser::Msg_UpdateDimensions. That reflow only happens off a refresh driver tick, and nothing forces one, so when no tick lands while the tab is opening the content process runs style and layout, fires DOMContentLoaded, load and pageshow, and reaches readyState complete while window.innerWidth is 0.

This is web observable: media queries evaluate against an empty viewport, getBoundingClientRect() returns zeros, and hit testing finds nothing because the root element's border box covers no point, so elementFromPoint() returns null everywhere. It also means layout-triggered subresource loads (fonts, images, image prioritisation by position) happen against a viewport that is not the real one.

Profiles of uriloader/exthandler/tests/mochitest/browser_pdf_save_as.js show the failing ordering as load and pageshow at 7.876s, then Msg_UpdateDimensions at 7.899s. In the passing cases the dimensions arrive first, 6-10ms after PBrowser::Msg_Show and before load.

In bug 1970802 comment 71 and comment 77, Gijs suggested best-guessing the initial viewport size when creating the docshell, so that there is never a 0x0 state. nsSubDocumentFrame::GetInitialSubdocumentSize() already has a fallback for this, but it returns 10x10 unless there is a detached presentation to copy from, and nsFrameLoader::ShowRemoteFrame() deliberately does not send a size before the first reflow (bug 820571).

Bug 1970802 addressed the test harness consequence, by making BrowserTestUtils.openNewForegroundTab wait for a tick before resolving. This bug is for the underlying behaviour.

Gonna transplant my needinfo from 1970802 to Emilio here.

Can we add optional args to whatever IPC is creating the content viewport/docshell and, for tabbed browsers, prefill them with what we expect, and/or is there a better/alternative way to avoid this race and improve the status quo here?

Flags: needinfo?(emilio)

Well, yeah, we could, in order of my gut feeling easier-to-harder stuff:

  • Fallback to a better size (WIP incoming, I don't know how that'll fare on try, we'll see).
  • Give the <browser> element a way of providing a fallback size in the DOM (what about width / height attributes? Something else).
  • Try to make sure that layout is clean before showing remote frames. This changes scheduling enough that makes me a bit scared. Though in practice it should be more consistent. Right now if you append a <browser> element there's nothing flushing layout by default until the refresh driver tick. But if you flush style via getComputedStyle you get into this weird situation where you have frames and trigger the Show(), but don't have layout and thus don't send a size.
Flags: needinfo?(emilio)

The fallback intrinsic size seems way better than 0, and reasonable
enough?

Assignee: nobody → emilio
Attachment #9635652 - Attachment description: WIP: Bug 2068549 - Use a more reasonable default size for remote browsers. → Bug 2068549 - Use a more reasonable default size for remote browsers. r=#layout
Status: NEW → ASSIGNED
Severity: -- → S3
Status: ASSIGNED → RESOLVED
Closed: 11 days ago
Resolution: --- → FIXED
Target Milestone: --- → 157 Branch

I think the intermittent failure I debugged at https://bugzilla.mozilla.org/show_bug.cgi?id=1924676#c58 had the same root cause.

See Also: → 1924676
QA Whiteboard: [qa-triage-done-c158/b157]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: