Open Bug 1584425 Opened 6 years ago Updated 3 years ago

Flash of unstyled content, with inline <style> rule that happens to come after an @import statement inside the <body>

Categories

(Core :: CSS Parsing and Computation, defect, P3)

Desktop
All
defect

Tracking

()

Tracking Status
firefox-esr60 --- affected
firefox-esr68 --- affected
firefox69 --- affected
firefox70 --- affected
firefox71 --- affected

People

(Reporter: dholbert, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(3 files, 1 obsolete file)

Attached file testcase 1

STR:

  1. Turn on network throttling (or just be on a slow connection):
  • F12 to open devtools
  • go to network tab
  • Click "no throttling" and pick "Regular 3G" (or slower)
  1. Load the attached testcase.
  2. Reload. (optional, but might help)

ACTUAL RESULTS:

  • Both lines of text are immediately visible.
  • There is initially a large red area separating them.

EXPECTED RESULTS:
The red area shouldn't show up, because it's styled as display:none inside of a <style> element that comes before it in the DOM.

The problem here is that there's an @import style in he <style> element which kicks off an async load, and that seems to delay the processing of the rest of the style element, but (in Firefox at least) it does not block the rendering of the rest of the page.

In Chrome, it does block the rendering of the rest of the page, so we see the first line of text render, and then only after the @import finishes loading does the remaining content appear. And the red area never renders, because it's display:none right away as soon as layout/styling get a chance to process it, it seems.

I encountered this in the wild at https://www.builddirect.com/ (which has a large SVG IE-logo graphic inside of a display:none subtree, which briefly flashes during pageload if your connnection is slow).

I strongly suspect this is the explanation for Google Calendar bug 1523596 (which I encounter quite often when loading Google Calendar).

Summary: Flash of unstyled content, with inline <style> that happens to @import something and restyle content after it → Flash of unstyled content, with inline <style> rule that happens to come after an @import statement
Attachment #9096820 - Attachment description: screencast of bug (flash of red), in this case not even using network throttling → screencast of bug (flash of red), in this case not even using network throttling. Bug is visible at 0:01 - 0:02

I can take a look. Curious if it's a regression.

Flags: needinfo?(emilio)

Bugbug thinks this bug is a regression, but please revert this change in case of error.

Keywords: regression

Doesn't seem to be.

I can confirm that this is not a recent regression. Occurs on builds af far as Release 50. Also, throttling is not needed to reproduce it.

OS: Unspecified → All
Hardware: Unspecified → Desktop

Well, so this is only if the <style> element is in the <body>, of course. If it's in the <head> it properly defers layout initialization.

Boris, you have been part of a lot of the discussions on this stuff, does Blink actually block the parser on external stylesheets even in the <body> as they intended in https://groups.google.com/a/chromium.org/d/msg/blink-dev/ZAPP8aTnyn0/JURBX5uFCAAJ?

Flags: needinfo?(emilio) → needinfo?(bzbarsky)
Summary: Flash of unstyled content, with inline <style> rule that happens to come after an @import statement → Flash of unstyled content, with inline <style> rule that happens to come after an @import statement inside the <body>

So there are two things we could do, I guess. One is that, another is applying the inline styles even if there are pending @import rules.

That's a bit of a perf footgun though, because that means that @import becomes an insert from the point of view of the cascade data, and that means we need to rebuild all later stylesheets to get the cascade order right.

Attached file Testcase for the behavior (obsolete) —

Per this testcase, it does look like at least Chrome Dev is blocking the parser in this situation....

Flags: needinfo?(bzbarsky)

From the point of view of real-life compat issues, another option would be to try to have the @import ready to go by the time the <style> is parsed.

On the https://www.builddirect.com/ site, for example, we have two external <link>s followed by some <script> tags, some external, all inside <head>. All that stuff needs to load before we ever get to the <body>. So if we loaded the @import in parallel with those, we would have at least some chance of avoiding the flash.

To do that, we'd need to have to fix bug 1546783.

Err, wrong bug

No longer regressed by: 1079662, 1489001
Depends on: 1546783

I think the @import in bz's testcase is getting blocked by bugzilla's CSP since it's an insecure (http) URL. At least, it's behaving as if the @import is blocked.

--> fixed to use an secure https URL instead.

Attachment #9096931 - Attachment is obsolete: true

(Worth noting, though probably unsurprising: Nightly still shows ACTUAL RESULTS here, so bug 1546783 didn't fix this. But per comment 9, it sounds like it may have gotten us closer.)

FWIW I cannot access the page from here:

Unfortunately the content you're trying to view is unavailable in your area.

See Also: → 1584088

That's unfortunate - but it probably doesn't matter too much, because I think the attached testcases should work (and are reasonable approximations/simplifications of the original page).

Version: unspecified → Trunk
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: