Skip to content

No engine implements the container document clause of "has a style sheet that is blocking scripts" #12678

Description

@awesomekling

What is the issue with the HTML Standard?

https://html.spec.whatwg.org/multipage/semantics.html#has-a-style-sheet-that-is-blocking-scripts

A Document document has a style sheet that is blocking scripts if the following steps return true:

  1. If document's script-blocking style sheet set is not empty, then return true.
  2. If document's node navigable is null, then return false.
  3. Let containerDocument be document's node navigable's container document.
  4. If containerDocument is non-null and containerDocument's script-blocking style sheet set is not empty, then return true.
  5. Return false.

Steps 2-4 make a still-loading stylesheet in a parent document block script execution in child navigable documents. As far as I can tell, no engine implements this as written:

  • Blink: consults only the document's own pending-sheet counter (StyleEngine::HaveScriptBlockingStylesheetsLoaded, via Document::IsScriptExecutionReady). No ancestor is ever consulted.
  • WebKit: same, Document::haveStylesheetsLoaded() only checks the local Style::Scope's pending sheets.
  • Gecko: consults ancestors, but (a) recursively through the whole ancestor chain, not just the container document, and (b) only for parser-blocking scripts (ScriptLoader::ReadyToExecuteParserBlockingScripts). Deferred and module scripts, which this algorithm also gates via "the end" step 5, only wait on the child document's own sheets in Gecko; only the pending parsing-blocking script path consults ancestors.

The clause dates to 2010 (r5663, W3C bug 10575), which codified Gecko's then-existing recursive behavior. The definition was silently flattened from "any ancestor" to "container document only" in the counter rewrite (#4031), so today's text matches Gecko neither in scope nor in which scripts it applies to. There also appears to be no WPT coverage of the container clause.

We implemented the clause as written in Ladybird and found it makes iframes wait on the embedding page's stylesheets in ways no other engine does (for example, ad iframes on amazon.com product pages idle for many seconds while the top document loads CSS).

Suggestion: remove steps 2-4, matching the two engines that never implemented them. Alternatively, if the FOUC concern from bug 10575 still stands, scope the clause to parser-blocking scripts and make it walk all ancestors, which is what Gecko actually ships.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions