Subframes can cause a flash of unstyled content (FOUC)

NEW
Unassigned

Status

()

Core
CSS Parsing and Computation
6 years ago
6 years ago

People

(Reporter: bz, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

Consider a page with this structure:

  <!DOCTYPE HTML>
  <head>
    <link rel="stylesheet" href="slow-server">
  </head>
  <body>
    <iframe src="something"></iframe>
  </body>


Normally, we would hold off starting layout on this document until the stylesheet has loaded.  However in this case when the iframe finishes loading it will try to fire its onload handler, which will flush style on the subframe document (to make sure we kick off background image loads and the like), which will flush layout on the parent document (due to possible media queries), which will start layout on the parent.  If all this happens before the stylesheet is loaded, we get a flash of unstyled content.

Obvious options are:

1)  Do nothing, just deal with it.  The situation where this will come up involves no <script> tags inside the <iframe> and not <script> tags in the parent document before the <iframe>, which is rare.

2)  Stop flushing style before firing onload.

3)  Stop flushing layout on the parent before firing onload.

4)  Stop triggering layout on the parent for layout flushes coming from kids
    firing onload.

5)  Hold off onload on subframes if the parent document has pending stylesheet
    loads.

6)  Block the parser on stylesheets again, now that we have a much better
    speculative parser.  The main drawback here, I think, is that we don't
    speculate some types of loads yet.  In particular, subframe loads.

Thoughts?
My personal preference is probably #5, except for the complexity it adds....
The parser currently has the capability to block only on </script>. Given that this problem isn't seen too often, I'd rather not choose solution #6.

#5 scares me having worked of the about:blank stuff, but maybe it'll be ok.
#5 sounds like a hack. #2 sounds good, but I know you ran into problems trying to avoid the reflow flush before onload...
My preference is also #5 (which I chose immediately after reading through the list, before seeing it was also bz's preference).  But I haven't thought about it much.
robert, the problem with #2 is that we would fire onload before loading CSS background images and the like....

I agree #5 sounds like a hack.  I'm not seeing too many clean solutions here.  :(

Henri, about:blank would not be affected too much.  It's not the load event itself that's a problem; it's the style flush we do in the docloader before firing it.  Synthetic load events from about:blank would not be affected at all.
Another option (call it #7) is to stop style flushes on the frame flushing layout in the parent, when the parent's painting is suppressed. We only do that to get media queries right (right?), and when the parent unsuppresses and reflows we'll fix up the media query results in the frame.
That's basically #4 above, I think.  I might not have described it clearly enough....

The main drawback of that approach is that onload on the subframe could fire before all the background images for the relevant media query that ends up matching are loaded.  This may not be a big worry, of course, esp since in the common case there is no media query.
(In reply to Boris Zbarsky (:bz) from comment #7)
> That's basically #4 above, I think.  I might not have described it clearly
> enough....

#4 doesn't depend on whether the parent's painting is suppressed. Maybe you meant that...
(In reply to Boris Zbarsky (:bz) from comment #7)
> The main drawback of that approach is that onload on the subframe could fire
> before all the background images for the relevant media query that ends up
> matching are loaded.  This may not be a big worry, of course, esp since in
> the common case there is no media query.

Also, while the parent document is incompletely loaded, you don't even know whether the geometry of the frame element that you use to resolve the media queries is its final geometry.
> #4 doesn't depend on whether the parent's painting is suppressed.

Indeed, but it does depend on the parent not having had InitialReflow called.  Since that's what sets up paint suppression, we can effectively assume that painting is "suppressed" before InitialReflow.

The key is to avoid the InitialReflow call on the parent.

Agreed on the parent document being incompletely loaded implying that iframe sizes may well just be bogus.  So maybe #4 is the way to go here....
You need to log in before you can comment on or make changes to this bug.