Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
<link> elements with media queries that do not affect the current pag…
…e can be delayed

https://bugs.webkit.org/show_bug.cgi?id=39455
rdar://102178226

Reviewed by Alan Baradlay.

We correctly deprioritize stylesheets with non-matching media attribute and don't make them
rendering blocking. However they may still delay the visually non-empty milestone. This delay
only comes into play if there is not enough visual content to trigger the milestone otherwise.
This may end up delaying rendering until the non-matching stylesheets are fully loaded on simple
pages.

* LayoutTests/http/tests/css/link-with-non-matching-media-slow-load-expected.html: Added.
* LayoutTests/http/tests/css/link-with-non-matching-media-slow-load.html: Added.
* Source/WebCore/page/FrameView.cpp:
(WebCore::FrameView::checkAndDispatchDidReachVisuallyNonEmptyState):

Ignore "very low" priority resources when determining if everything important is loaded.

* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::isVisuallyNonEmpty const):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:

Testing support.

Canonical link: https://commits.webkit.org/259963@main
  • Loading branch information
anttijk committed Feb 7, 2023
1 parent c54e9a9 commit 9e31d4e
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 0 deletions.
@@ -0,0 +1,5 @@
<style>
#pass { display:inline; width:200px; height:200px; background-color: green; position: absolute; }
</style>
<body>
<div id=pass>PASS: Non-matching slow stylesheet didn't delay visually non-empty.</div>
@@ -0,0 +1,18 @@
<style>
#pass { display:none; width:200px; height:200px; background-color: green; position: absolute; }
#fail { display:inline; width:200px; height:200px; background-color: red; position: absolute; }
</style>
<body>
<link rel="stylesheet" href="http://127.0.0.1:8000/local/slow-css-pass.cgi" media="not all" onload="this.media='all'">
<div id=pass></div>
<div id=fail></div>
<script>
function test() {
document.body.offsetLeft;

if (window.internals)
pass.textContent = internals.isVisuallyNonEmpty ? "PASS: Non-matching slow stylesheet didn't delay visually non-empty." : "FAIL: Non-matching slow media delayed visually non-empty.";
}

setTimeout(test);
</script>
3 changes: 3 additions & 0 deletions Source/WebCore/page/FrameView.cpp
Expand Up @@ -5069,6 +5069,9 @@ void FrameView::checkAndDispatchDidReachVisuallyNonEmptyState()
for (auto& resource : resources) {
if (resource.value->isLoaded())
continue;
// ResourceLoadPriority::VeryLow is used for resources that are not needed to render.
if (resource.value->loadPriority() == ResourceLoadPriority::VeryLow)
continue;
if (resource.value->type() == CachedResource::Type::CSSStyleSheet || resource.value->type() == CachedResource::Type::FontResource)
return true;
}
Expand Down
10 changes: 10 additions & 0 deletions Source/WebCore/testing/Internals.cpp
Expand Up @@ -7014,4 +7014,14 @@ Internals::SelectorFilterHashCounts Internals::selectorFilterHashCounts(const St
return { hashes.ids.size(), hashes.classes.size(), hashes.tags.size(), hashes.attributes.size() };
}

bool Internals::isVisuallyNonEmpty() const
{
auto* document = contextDocument();
if (!document || !document->frame())
return false;

auto* frameView = document->frame()->view();
return frameView && frameView->isVisuallyNonEmpty();
}

} // namespace WebCore
2 changes: 2 additions & 0 deletions Source/WebCore/testing/Internals.h
Expand Up @@ -1369,6 +1369,8 @@ class Internals final : public RefCounted<Internals>, private ContextDestruction
};
SelectorFilterHashCounts selectorFilterHashCounts(const String& selector);

bool isVisuallyNonEmpty() const;

private:
explicit Internals(Document&);
Document* contextDocument() const;
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/testing/Internals.idl
Expand Up @@ -1194,4 +1194,6 @@ typedef (FetchRequest or FetchResponse) FetchObject;
boolean consumeTransientActivation();

SelectorFilterHashCounts selectorFilterHashCounts(DOMString selector);

readonly attribute boolean isVisuallyNonEmpty;
};

0 comments on commit 9e31d4e

Please sign in to comment.