Skip to content

Commit

Permalink
Bug 1873933 [wpt PR 43920] - Reland: [soft navigations] Ignore non-at…
Browse files Browse the repository at this point in the history
…tributed LCP before softnav detection, a=testonly

Automatic update from web-platform-tests
Reland: [soft navigations] Ignore non-attributed LCP before softnav detection (#43920)

This relands a commit from pre-121 branch, with a number of fixes
applied as well as tests and changes to adapt to commits landed since
that branch.

------------------------------------------------------------------------
Original commit message:

This CL ignores LCPs that are not attributed to the soft navigation
task after a user interaction and before a soft navigation was
detected, as discussed in [1].

It also fixes a bug in soft navigation detection in the case where all
paints arrive before the URL was changed. Currently in such cases, a
soft navigation entry is not emitted. This CL fixes that.

[1] WICG/soft-navigations#29 (comment)
------------------------------------------------------------------------

The full set of relanded patches here is:

* commit 6e358318d16c22292d0e57ed7542fe3761c42a72.
    "[soft navigations] Ignore non-attributed LCP before softnav detection"

* commit 81fd9fb434f38f1411baae1e30835c21011974e8.
    "[soft-navigations] Fix crash when user interaction precedes softnav"

* commit 596e49410759e65ee39d5ffb22f8e4789b5d836b.
    "Create ScriptState::Scope in SetCurrentTimeAsStartTime()"

* commit 6039f57d5e4bf6817f6ca4e75ea65e864fcfc2cf.
    "Move SoftNavigation end of event emission to a handle based on isolate"

* commit afec46c737c5547302fa35a3944624df44fad755.
    "Fix crash by adding v8::HandleScope in SameDocumentCommit"

Bug: 1505994
Change-Id: Ibf6d7d22375a1b0fc74e0fe31178831a738d8a46
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5185654
Reviewed-by: Michal Mocny <mmocny@chromium.org>
Commit-Queue: Ian Clelland <iclelland@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1248389}

Co-authored-by: Ian Clelland <iclelland@chromium.org>
--

wpt-commits: 2cc070d161f7e6fbd9a1d5bd0507aba48d42f1e6
wpt-pr: 43920
  • Loading branch information
chromium-wpt-export-bot authored and moz-wptsync-bot committed Jan 20, 2024
1 parent e6e0468 commit d5071ff
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/soft-navigation-helper.js"></script>
</head>
<body>
<main id=main>
<div>
<a id=link><img src="/images/lcp-256x256.png" id="img"></a>
</div>
</main>
<script>
const link = document.getElementById("link");
let first_lcp_painted;
let second_lcp_painted;
(async () => {
await new Promise(r => { first_lcp_painted = r; });
addImageToMain("lcp-133x106.png", "no_lcp");
(new PerformanceObserver(second_lcp_painted)).observe({type: "element"});
})();
testSoftNavigation({
pushState: null,
clicks: 2,
addContent: async () => {
// Add an LCP element.
await new Promise(resolve => {
addImageToMain("lcp-100x50.png", "first_lcp" + counter);
(new PerformanceObserver(resolve)).observe({type: "element"});
});
if(counter) {
first_lcp_painted();
// Wait for the unrelated LCP to be painted.
await new Promise(r => { second_lcp_painted = r; });
}
const url = URL + "?" + counter;
history.pushState({}, '', url);
},
link: link,
validate: async () => {
const lcps = await getLcpEntries();
const ref_counter = counter-1;
assert_equals(lcps.length, 2 + ref_counter, "Got 2 LCP entries");
assert_equals(lcps[lcps.length - 1].id, "first_lcp" + ref_counter,
"Got the first LCP");
},
test: "Second soft navigation image LCP discovered between user " +
"interaction and soft navigation detection are properly " +
"reported, while unrelated LCPs are ignored during that time. " +
"As a side effect, we also test element timing."});
</script>
</body>
</html>



Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/soft-navigation-helper.js"></script>
</head>
<body>
<main id=main>
<div>
<a id=link><img src="/images/lcp-256x256.png" id="img"></a>
</div>
</main>
<script>
const link = document.getElementById("link");
let first_lcp_painted;
let second_lcp_painted;
(async () => {
await new Promise(r => { first_lcp_painted = r; });
addImageToMain("lcp-133x106.png", "no_lcp");
(new PerformanceObserver(second_lcp_painted)).observe({type: "element"});
})();
testSoftNavigation({
pushState: null,
addContent: async () => {
// Add an LCP element.
await new Promise(resolve => {
addImageToMain("lcp-100x50.png", "first_lcp");
(new PerformanceObserver(resolve)).observe({type: "element"});
});
first_lcp_painted();
// Wait for the unrelated LCP to be painted.
await new Promise(r => { second_lcp_painted = r; });
const url = URL + "?" + counter;
history.pushState({}, '', url);
},
link: link,
validate: async () => {
const lcps = await getLcpEntries();
assert_equals(lcps.length, 2, "Got 2 LCP entries");
assert_equals(lcps[lcps.length - 1].id, "first_lcp", "Got the first LCP");
},
test: "Image LCP discovered between user interaction and soft " +
"navigation detection are properly reported, while unrelated " +
"LCPs are ignored during that time. As a side effect, we also " +
"test element timing."});
</script>
</body>
</html>


Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/soft-navigation-helper.js"></script>
</head>
<body>
<main id=main>
<div>
<a id=link><img src="/images/lcp-256x256.png" id="img"></a>
<a id=not_nav><img src="/images/lcp-16x16.png"></a>
</div>
</main>
<script>
// Push state a couple of times
history.pushState({}, "", "foobar.html");
history.pushState({}, "", "anotherOne.html");

(async () => {
const link = document.getElementById("link");
// Trigger a user interaction that doesn't result in a soft navigation, but
// does paint.
await (async () => {
const not_nav = document.getElementById("not_nav");
let non_soft_nav_click;
const non_soft_nav_click_promise =
new Promise(r => { non_soft_nav_click = r; });
not_nav.addEventListener("click", () => {
addImageToMain("lcp-133x106.png", "not_soft_nav_image");
(new PerformanceObserver(non_soft_nav_click)).observe({type: "element"});
});
if (test_driver) {
test_driver.click(not_nav);
}
await non_soft_nav_click_promise;
})();
const url = URL + "?" + counter;
link.addEventListener("click", () => {
// Add an LCP element.
const img = new Image();
img.src = '/images/lcp-100x500.png' + "?" + Math.random();
document.getElementById("main").appendChild(img);
history.back();
});
promise_test(async t => {
if (test_driver) {
test_driver.click(link);
}
await waitOnSoftNav();
assert_equals(
document.softNavigations, 1,
'Single Soft Navigation detected');
const [entries, options] = await new Promise(resolve => {
(new PerformanceObserver((list, obs, options) => resolve(
[list.getEntries(), options]))).observe(
{type: 'soft-navigation', buffered: true});
});

assert_equals(entries.length, 1,
"Performance observer got an entry");
}, "Ensure that soft navigation entry emitted through a synchronous " +
"event that modified DOM and committed a same document navigation, " +
"and that was preceded by a user intreaction that resulted in a " +
"contentful paint is properly detected.");
})();
</script>
</body>
</html>




Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const MAX_CLICKS = 50;
const MAX_PAINT_ENTRIES = 51;
const URL = "foobar.html";
const readValue = (value, defaultValue) => {
return value != undefined ? value : defaultValue;
return value !== undefined ? value : defaultValue;
}
const testSoftNavigation =
options => {
Expand Down Expand Up @@ -291,15 +291,16 @@ const getLcpEntriesWithoutSoftNavs = async () => {
return entries;
};

const addImage = async (element, url="blue.png") => {
const addImage = async (element, url="blue.png", id = "imagelcp") => {
const img = new Image();
img.src = '/images/'+ url + "?" + Math.random();
img.id="imagelcp";
img.id=id
img.setAttribute("elementtiming", id);
await img.decode();
element.appendChild(img);
};
const addImageToMain = async (url="blue.png") => {
await addImage(document.getElementById('main'), url);
const addImageToMain = async (url="blue.png", id = "imagelcp") => {
await addImage(document.getElementById('main'), url, id);
};

const addTextParagraphToMain = (text, element_timing = "") => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/soft-navigation-helper.js"></script>
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
</head>
<body>
<main id=main>
<div>
<a id=link><img src="/images/lcp-256x256.png" id="img"></a>
</div>
</main>
<script>
const link = document.getElementById("link");
let first_lcp_painted;
let second_lcp_painted;
(async () => {
await new Promise(r => { first_lcp_painted = r; });
addTextParagraphToMain("LOREM IPSUMR", "no lcp");
(new PerformanceObserver(second_lcp_painted)).observe({type: "element"});
})();
testSoftNavigation({
pushState: null,
clicks: 2,
addContent: async () => {
// Add an LCP element.
await new Promise(resolve => {
const p = addTextParagraphToMain("Lorem Ipsum", /*element_timing=*/"first_lcp" + counter);
p.id = "first_lcp" + counter;
(new PerformanceObserver(resolve)).observe({type: "element"});
});
if(counter) {
first_lcp_painted();
// Wait for the unrelated LCP to be painted.
await new Promise(r => { second_lcp_painted = r; });
}
const url = URL + "?" + counter;
history.pushState({}, '', url);
},
link: link,
validate: async () => {
const lcps = await getLcpEntries();
const ref_counter = counter-1;
assert_equals(lcps.length, 2 + ref_counter, "Got 2 LCP entries");
assert_equals(lcps[lcps.length - 1].id, "first_lcp" + ref_counter, "Got the first LCP");
},
test: "Second soft navigation text LCP discovered between user " +
"interaction and soft navigation detection are properly " +
"reported, while unrelated LCPs are ignored during that time. " +
"As a side effect, we also test element timing."});
</script>
</body>
</html>




Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="resources/soft-navigation-helper.js"></script>
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
</head>
<body>
<main id=main>
<div>
<a id=link><img src="/images/lcp-256x256.png" id="img"></a>
</div>
</main>
<script>
const link = document.getElementById("link");
let first_lcp_painted;
let second_lcp_painted;
(async () => {
await new Promise(r => { first_lcp_painted = r; });
addTextParagraphToMain("LOREM IPSUMR", "no lcp");
(new PerformanceObserver(second_lcp_painted)).observe({type: "element"});
})();
testSoftNavigation({
pushState: null,
addContent: async () => {
// Add an LCP element.
await new Promise(resolve => {
const p = addTextParagraphToMain("Lorem Ipsum", /*element_timing=*/"first_lcp");
p.id = "first_lcp";
(new PerformanceObserver(resolve)).observe({type: "element"});
});
first_lcp_painted();
// Wait for the unrelated LCP to be painted.
await new Promise(r => { second_lcp_painted = r; });
const url = URL + "?" + counter;
history.pushState({}, '', url);
},
link: link,
validate: async () => {
const lcps = await getLcpEntries();
assert_equals(lcps.length, 2, "Got 2 LCP entries");
assert_equals(lcps[lcps.length - 1].id, "first_lcp", "Got the first LCP");
},
test: "Text LCP discovered between user interaction and soft " +
"navigation detection are properly reported, while unrelated " +
"LCPs are ignored during that time. As a side effect, we also " +
"test element timing."});
</script>
</body>
</html>

0 comments on commit d5071ff

Please sign in to comment.