Bug 1765615 - Handle most changes to CSS contain and content-visibility without needing to reconstruct frames. r=layout-reviewers,emilio
Right now, we reconstruct frames in response to a change in the CSS `contain` property or `content-visibility`. This patch tries to optimize this a bit: 1. Updates involving style containment change continue to force a reconstruction, due to the need to handle counters/quotes. 2. Updates involving paint/layout containment change only force a reconstruction if it's needed to handle absolutely/fixed positioned descendants or floats (for this one, see also bug 1874826). 3. Other containment changes will only force a reflow and repaint. Per the CSS contain spec, layout, style and paint containments are enabled for `content-visibility: hidden` and `content-visibility: auto`. As a consequence, changing `content-visibility` between `hidden` and `auto` values no longer requires reconstruction. Changing between these values and `visible` may need a reconstruction although authors may generally avoid that in practice by forcing `style` containment. Differential Revision: https://phabricator.services.mozilla.com/D197043
This commit is contained in:
@@ -2192,8 +2192,6 @@ void PresShell::NotifyDestroyingFrame(nsIFrame* aFrame) {
|
||||
mPendingScrollAnchorAdjustment.Remove(scrollableFrame);
|
||||
mPendingScrollResnap.Remove(scrollableFrame);
|
||||
}
|
||||
|
||||
mContentVisibilityAutoFrames.Remove(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11996,15 +11994,12 @@ void PresShell::UpdateRelevancyOfContentVisibilityAutoFrames() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isRelevantContentChanged = false;
|
||||
for (nsIFrame* frame : mContentVisibilityAutoFrames) {
|
||||
isRelevantContentChanged |=
|
||||
frame->UpdateIsRelevantContent(mContentVisibilityRelevancyToUpdate);
|
||||
frame->UpdateIsRelevantContent(mContentVisibilityRelevancyToUpdate);
|
||||
}
|
||||
if (isRelevantContentChanged) {
|
||||
if (nsPresContext* presContext = GetPresContext()) {
|
||||
presContext->UpdateHiddenByContentVisibilityForAnimations();
|
||||
}
|
||||
|
||||
if (nsPresContext* presContext = GetPresContext()) {
|
||||
presContext->UpdateHiddenByContentVisibilityForAnimationsIfNeeded();
|
||||
}
|
||||
|
||||
mContentVisibilityRelevancyToUpdate.clear();
|
||||
@@ -12038,7 +12033,6 @@ PresShell::ProximityToViewportResult PresShell::DetermineProximityToViewport() {
|
||||
auto input = DOMIntersectionObserver::ComputeInput(
|
||||
*mDocument, /* aRoot = */ nullptr, &rootMargin);
|
||||
|
||||
bool isRelevantContentChanged = false;
|
||||
for (nsIFrame* frame : mContentVisibilityAutoFrames) {
|
||||
auto* element = frame->GetContent()->AsElement();
|
||||
result.mAnyScrollIntoViewFlag |=
|
||||
@@ -12059,8 +12053,7 @@ PresShell::ProximityToViewportResult PresShell::DetermineProximityToViewport() {
|
||||
.Intersects();
|
||||
element->SetVisibleForContentVisibility(intersects);
|
||||
if (oldVisibility.isNothing() || *oldVisibility != intersects) {
|
||||
isRelevantContentChanged |=
|
||||
frame->UpdateIsRelevantContent(ContentRelevancyReason::Visible);
|
||||
frame->UpdateIsRelevantContent(ContentRelevancyReason::Visible);
|
||||
}
|
||||
|
||||
// 14.2.3.3
|
||||
@@ -12068,10 +12061,8 @@ PresShell::ProximityToViewportResult PresShell::DetermineProximityToViewport() {
|
||||
result.mHadInitialDetermination = true;
|
||||
}
|
||||
}
|
||||
if (isRelevantContentChanged) {
|
||||
if (nsPresContext* presContext = GetPresContext()) {
|
||||
presContext->UpdateHiddenByContentVisibilityForAnimations();
|
||||
}
|
||||
if (nsPresContext* presContext = GetPresContext()) {
|
||||
presContext->UpdateHiddenByContentVisibilityForAnimationsIfNeeded();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user