mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1794415 - Force reflow of fewer anonymous children of content-visibility: hidden
r=emilio
Reflow fewer types of anonymous children (only anonymous blocks) of `content-visibility: hidden` elements. This reduces the number of reflows for skipped content. This also adjusts to the implementation of IsHiddenByContentVisibilityOnAnyAncestor() to match the implementation of IsHiddenByContentVisibilityOfInFlowParentForLayout() in only skipping one layer of anonymous content. Differential Revision: https://phabricator.services.mozilla.com/D158961
This commit is contained in:
parent
f47fc4dad4
commit
683c8233a4
@ -6734,6 +6734,7 @@ void nsIFrame::DidReflow(nsPresContext* aPresContext,
|
||||
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("nsIFrame::DidReflow"));
|
||||
|
||||
if (IsHiddenByContentVisibilityOfInFlowParentForLayout()) {
|
||||
RemoveStateBits(NS_FRAME_IN_REFLOW | NS_FRAME_FIRST_REFLOW);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6855,7 +6856,8 @@ bool nsIFrame::HidesContentForLayout() const {
|
||||
|
||||
bool nsIFrame::IsHiddenByContentVisibilityOfInFlowParentForLayout() const {
|
||||
const auto* parent = GetInFlowParent();
|
||||
return parent && parent->HidesContentForLayout() && !Style()->IsAnonBox();
|
||||
return parent && parent->HidesContentForLayout() &&
|
||||
!(Style()->IsAnonBox() && !IsFrameOfType(nsIFrame::eLineParticipant));
|
||||
}
|
||||
|
||||
bool nsIFrame::IsHiddenByContentVisibilityOnAnyAncestor() const {
|
||||
@ -6863,18 +6865,17 @@ bool nsIFrame::IsHiddenByContentVisibilityOnAnyAncestor() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAnonymousBox = Style()->IsAnonBox();
|
||||
bool isAnonymousBlock =
|
||||
Style()->IsAnonBox() && !IsFrameOfType(nsIFrame::eLineParticipant);
|
||||
for (nsIFrame* cur = GetInFlowParent(); cur; cur = cur->GetInFlowParent()) {
|
||||
if (!isAnonymousBlock && cur->HidesContent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Anonymous boxes are not hidden by the content-visibility of their first
|
||||
// non-anonymous ancestor, but can be hidden by ancestors further up the
|
||||
// tree.
|
||||
if (isAnonymousBox && !cur->Style()->IsAnonBox()) {
|
||||
isAnonymousBox = false;
|
||||
}
|
||||
|
||||
if (!isAnonymousBox && cur->HidesContent()) {
|
||||
return true;
|
||||
}
|
||||
isAnonymousBlock = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Contain: Test content-visibility:hidden reflow counts</title>
|
||||
<link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com">
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body style="content-visibility: hidden;">
|
||||
hello
|
||||
</body>
|
||||
|
||||
<script>
|
||||
let gUtils = SpecialPowers.getDOMWindowUtils(window);
|
||||
let gTestContainer = document.getElementById("test");
|
||||
|
||||
function flushLayout() {
|
||||
document.documentElement.offsetHeight;
|
||||
}
|
||||
|
||||
function getReflowCount() {
|
||||
flushLayout();
|
||||
return gUtils.framesReflowed;
|
||||
}
|
||||
|
||||
function runTestFunctionAndCountReflows(testFunction) {
|
||||
const beforeCount = getReflowCount();
|
||||
testFunction();
|
||||
const afterCount = getReflowCount();
|
||||
console.log(afterCount - beforeCount);
|
||||
return afterCount - beforeCount;
|
||||
}
|
||||
|
||||
test(() => {
|
||||
flushLayout();
|
||||
|
||||
const reflows = runTestFunctionAndCountReflows(() => {
|
||||
document.body.innerText = "something else";
|
||||
});
|
||||
assert_equals(reflows, 1, "Reflow only triggered on body.");
|
||||
}, "Changing text of 'content-visibility: hidden' body only triggers a single reflow.");
|
||||
</script>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user