Open Bug 1571644 Opened 1 year ago Updated 10 months ago

Messages rendered as blank lines during slow reflows when DevTools are rendered in a content frame

Categories

(DevTools :: about:debugging, task, P3)

task

Tracking

(Not tracked)

People

(Reporter: jdescottes, Unassigned)

References

Details

Attachments

(1 file)

(Note that Bug 1571349 will hide the issue, so when it lands you need to make sure to use a prior changeset)

STRs

  • open a first tab on https://sugared-oil.glitch.me/ (this page contains ~2000 CSS warnings, CSS warnings seem much heavier to render than normal messages)
  • open a second tab on about:debugging
  • select This Nightly
  • find the tab corresponding to sugared-oil.glitch.me (note, if this is not a local build, you have to enable local tab debugging by flipping devtools.aboutdebugging.local-tab-debugging to true)
  • click on inspect
  • in the about:devtools-toolbox tab that just opened, select the Console panel
  • in the console filters enable CSS Warnings, CSS in the filter bar
  • hover on the message list

ER: The messages should not become blank after hover
AR: Messages are blank after hover (see attached video)

Additional info

If you try to open the regular DevTools on https://sugared-oil.glitch.me/, hovering the messages will be slow, but lines will not go blank. The reason I am using about:debugging+about:devtools-toolbox for the test case is that it forces the toolbox to load in a frame with type="content" instead of "chrome". But I actually found the issue while working on Bug 1539979, and I had the issue in the regular toolbox as soon as I set "type" to "content" for the toolbox frame.

So about:debugging/about:devtools-toolbox recreates a similar environment, but it's something that might happen to regular DevTools as soon as we land Bug 1539979.

Profiles

We recorded two profiles:

And Nicolas also extracted a comparison:
https://profiler.firefox.com/compare/stack-chart/?globalTrackOrder=0-1-2&profiles[]=https%3A%2F%2Fperfht.ml%2F31fPOaE&profiles[]=https%3A%2F%2Fperfht.ml%2F31gMKeq&thread=0&v=4

So it seems reflow/rendering is behaving differently depending on the frame type.

Daniel, maybe you know what could explain this rendering difference between frames with type="chrome" and type="content"?

Flags: needinfo?(dholbert)

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: General → about:debugging
Component: about:debugging → General

I don't know offhand what type="chrome" vs. type="content" trigger, but I suspect the blank lines are happening due to some interaction with the compositor. (I can imagine that maybe the chrome vs. content type attribute could impact what sorts of inputs we've got for the compositor and/or how it operates, but that's just a guess -- I truly don't know what those attributes do.)

RE the compositor -- to illustrate my guess, here's a profile I recorded when following the STR, with a screenshots track at the top: https://perfht.ml/2T9WMen

If you hover the screenshots track and move your cursor from before to after a composite operation, you can see that the compositor-thread's bursts are the moments where the blank lines appear/disappear. I'd suggest asking someone on the graphics team about what's responsible for that blanking.

(Side note: the long reflow times here are pretty horrible and should be spun off to another bug, if they're not already tracked in a bug... They seem bad regardless of whether the type is chrome or content. i.e. they're pretty long in both profiles from comment 0.)

Flags: needinfo?(dholbert)

The restyle/reflow/repaint here is all to do with the :hover-triggered blue "tile" at the far left edge of each log entry:

.message:hover::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  bottom: 0;
  background: var(--theme-highlight-blue);
  width: 3px;
}

That pseudo-element insertion/removal on hover/unhover is what's causing all the work here. You can optimize this a great deal if you just cause that pseudo-element to be always present, and simply change its color to be visible/invisible on hover. In particular, just add this rule (same as the one above, but without "hover" and with background:transparent):

.message::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: 0;
    bottom: 0;
    background: transparent;
    width: 3px;
}

With that change, the long reflows disappear from my profile, and I don't notice any white flashing.

Does that work for you?

Flags: needinfo?(jdescottes)

(If you do take this strategy, you would probably want to adjust the ":hover" version of the rule so that it only bothers setting background and doesn't touch any of the other properties that are set in the new more-general ::before rule)

Hi Daniel! Thanks for taking a look, and yes the proposed patch works. Nicolas will either do that or remove the blue border completely in Bug 1571349. The goal of this bug is to try to understand why we had blank lines when using type=content.

I am worried that other slow-ish reflows in DevTools might also trigger this, on low end machines, leading to flashing UIs for users.

Flags: needinfo?(jdescottes)

Yeah, it's a graphics artifact so it'd need some info from someone more familiar with our painting/compositing codepath.

I'm guessing that maybe the ::hover-trigered abspos pseudo-element creation might cause us to throw away some piece of our display list (or a layer, or something else in our painting architecture) and then we recomposite in the interim and don't have anything to paint for some reason. But I'm not sure.

miko, do you have any ideas about what might be going on here?

Flags: needinfo?(mikokm)

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

miko, do you have any ideas about what might be going on here?

Unfortunately no. I think that I found the place with some documentation about the type attribute1, but without a simplified standalone testcase, figuring out how this exactly affects painting seems difficult.

Some possibilities that I spotted from reading the code:

  • WebRender tile caching is enabled for top level content2
  • Refresh driver is sometimes stopped for non-top level content3
  • Scrolling uses different display port size for root documents4
  • Top level content events might have higher priority5
Flags: needinfo?(mikokm)

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: General → about:debugging
You need to log in before you can comment on or make changes to this bug.