Commit e1e1bb4a authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Chromium LUCI CQ

Ignore layout shift under opacity:0

Bug: 1152869
Change-Id: Ie68a761a3cd2a81dcdd3de6d2469d64146c3f596
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2591907
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837687}
parent 447676f6
...@@ -11,6 +11,9 @@ shift. Now we also consider the previous visibility and ignore layout shift in ...@@ -11,6 +11,9 @@ shift. Now we also consider the previous visibility and ignore layout shift in
the case. the case.
[Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2591367) [Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2591367)
### Ignore layout shift under opacity:0
[Source code for this change](https://chromium-review.googlesource.com/c/chromium/src/+/2591907)
## How does this affect a site's metrics? ## How does this affect a site's metrics?
All of these changes only affect sites with specific types of content. Here are All of these changes only affect sites with specific types of content. Here are
...@@ -21,6 +24,11 @@ the specifics for each change: ...@@ -21,6 +24,11 @@ the specifics for each change:
Sites using visibility:hidden to hide layout changes may see a decrease in Sites using visibility:hidden to hide layout changes may see a decrease in
their Cumulative Layout Shift scores. their Cumulative Layout Shift scores.
### Ignore layout shift under opacity:0
Sites using opacity:0 to hide layout changes should see a decrease in their
Cumulative Layout Shift scores.
## When were users affected? ## When were users affected?
Chrome 89 is currently scheduled to be released the week of March 2, 2021. Chrome 89 is currently scheduled to be released the week of March 2, 2021.
...@@ -4,6 +4,7 @@ This is a list of changes to [Cumulative Layout Shift](https://web.dev/cls). ...@@ -4,6 +4,7 @@ This is a list of changes to [Cumulative Layout Shift](https://web.dev/cls).
* Chrome 89 * Chrome 89
* Metric definition improvement: [Ignore layout shift when visibility:hidden becomes visible](2020_12_cls.md) * Metric definition improvement: [Ignore layout shift when visibility:hidden becomes visible](2020_12_cls.md)
* Metric definition improvement: [Ignore layout shift under opacity:0](2020_12_cls.md)
* Chrome 88 * Chrome 88
* Metric definition improvement: [Cumulative layout shift properly detects shifts of fixed position elements](2020_11_cls.md) * Metric definition improvement: [Cumulative layout shift properly detects shifts of fixed position elements](2020_11_cls.md)
* Metric definition improvement: [Cumulative layout shift properly detects shifts of descendents of a sticky element](2020_11_cls.md) * Metric definition improvement: [Cumulative layout shift properly detects shifts of descendents of a sticky element](2020_11_cls.md)
......
...@@ -176,6 +176,11 @@ void PaintInvalidator::UpdateLayoutShiftTracking( ...@@ -176,6 +176,11 @@ void PaintInvalidator::UpdateLayoutShiftTracking(
if (!object.ShouldCheckGeometryForPaintInvalidation()) if (!object.ShouldCheckGeometryForPaintInvalidation())
return; return;
if (tree_builder_context.this_or_ancestor_opacity_is_zero) {
object.GetMutableForPainting().SetShouldSkipNextLayoutShiftTracking(true);
return;
}
auto& layout_shift_tracker = object.GetFrameView()->GetLayoutShiftTracker(); auto& layout_shift_tracker = object.GetFrameView()->GetLayoutShiftTracker();
if (!layout_shift_tracker.NeedsToTrack(object)) { if (!layout_shift_tracker.NeedsToTrack(object)) {
object.GetMutableForPainting().SetShouldSkipNextLayoutShiftTracking(true); object.GetMutableForPainting().SetShouldSkipNextLayoutShiftTracking(true);
......
...@@ -1295,8 +1295,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() { ...@@ -1295,8 +1295,9 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
} }
} }
if (properties_->Effect()) { if (const auto* effect = properties_->Effect()) {
context_.current_effect = properties_->Effect(); context_.current_effect = effect;
context_.this_or_ancestor_opacity_is_zero |= effect->Opacity() == 0;
if (properties_->MaskClip()) { if (properties_->MaskClip()) {
context_.current.clip = context_.absolute_position.clip = context_.current.clip = context_.absolute_position.clip =
context_.fixed_position.clip = properties_->MaskClip(); context_.fixed_position.clip = properties_->MaskClip();
......
...@@ -129,6 +129,7 @@ struct PaintPropertyTreeBuilderFragmentContext { ...@@ -129,6 +129,7 @@ struct PaintPropertyTreeBuilderFragmentContext {
// Therefore, we don't need extra bookkeeping for effect nodes and can // Therefore, we don't need extra bookkeeping for effect nodes and can
// generate the effect tree from a DOM-order traversal. // generate the effect tree from a DOM-order traversal.
const EffectPaintPropertyNodeOrAlias* current_effect; const EffectPaintPropertyNodeOrAlias* current_effect;
bool this_or_ancestor_opacity_is_zero = false;
// If the object is a flow thread, this records the clip rect for this // If the object is a flow thread, this records the clip rect for this
// fragment. // fragment.
......
<!DOCTYPE html>
<title>Layout Instability: opacity:0</title>
<link rel="help" href="https://wicg.github.io/layout-instability/" />
<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; opacity: 0"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/util.js"></script>
<script>
promise_test(async () => {
const watcher = new ScoreWatcher;
// Wait for the initial render to complete.
await waitForAnimationFrames(2);
// Shift target, for which no shift should be reported because it's not visible.
target.style.top = '200px';
target.style.opacity = 0.9;
await waitForAnimationFrames(2);
assert_equals(watcher.score, 0);
// Shift again, for which shift should be reported.
target.style.top = '300px';
await watcher.promise;
const expectedScore = computeExpectedScore(200 * (200 + 100), 100);
assert_equals(watcher.score, expectedScore);
}, 'opacity:0');
</script>
<!DOCTYPE html>
<title>Layout Instability: opacity:0</title>
<link rel="help" href="https://wicg.github.io/layout-instability/" />
<div id="target" style="position: absolute; top: 0; width: 400px; height: 400px; opacity: 0">
<div id="child" style="position: relative; top: 0; width: 200px; height: 200px; opacity: 0.5"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/util.js"></script>
<script>
promise_test(async () => {
const watcher = new ScoreWatcher;
// Wait for the initial render to complete.
await waitForAnimationFrames(2);
// Shift target, for which no shift should be reported because it's not visible.
target.style.top = '200px';
await waitForAnimationFrames(2);
assert_equals(watcher.score, 0);
// Shift child, for which no shift should be reported, either.
child.style.top = '100px';
await waitForAnimationFrames(2);
assert_equals(watcher.score, 0);
}, 'opacity:0');
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment