Speculation measurement - renderer source of truth [chromium/src : main]

0 views
Skip to first unread message

Hiroki Nakagawa (Gerrit)

unread,
Jul 30, 2026, 6:59:43 AM (23 hours ago) Jul 30
to Yoav Weiss (@Shopify), Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
Attention needed from Vladimir Levin and Yoav Weiss (@Shopify)

Hiroki Nakagawa added 6 comments

Patchset-level comments
File-level comment, Patchset 12 (Latest):
Hiroki Nakagawa . resolved

Looks good overall, but I didn't have time to fully read through test codes. I'll take another look later.

File third_party/blink/web_tests/TestExpectations
Line 3124, Patchset 11:# performance.getSpeculations().navigations reports the renderer's activated
Hiroki Nakagawa . unresolved

Can you add a blank line between line 3123 and 3124?

Line 3132, Patchset 11:crbug.com/532860179 virtual/speculation-rules-renderer-side-heuristics/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations.tentative.https.html [ Pass ]
Hiroki Nakagawa . unresolved

Can you add a blank line between 3132 and 3133 to make the block clear?

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
Line 45, Patchset 12 (Latest): { source: 'list', urls: moderateUrls, eagerness: 'moderate' },
Hiroki Nakagawa . unresolved

Can you remove this deprecated "source" param here and from other places in this file?

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-pointerdown.tentative.https.html
Line 63, Patchset 12 (Latest): source: 'document',
Hiroki Nakagawa . unresolved

Ditto.

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
Line 92, Patchset 12 (Latest): {source: 'list', urls: [barrierUrl], eagerness: 'immediate'},
Hiroki Nakagawa . unresolved

Can you remove this deprecated "source" param?

Open in Gerrit

Related details

Attention is currently required from:
  • Vladimir Levin
  • Yoav Weiss (@Shopify)
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
Gerrit-Change-Number: 8070441
Gerrit-PatchSet: 12
Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
Gerrit-CC: Nate Chapin <jap...@chromium.org>
Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
Gerrit-Attention: Yoav Weiss (@Shopify) <yoav...@chromium.org>
Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
Gerrit-Comment-Date: Thu, 30 Jul 2026 10:59:17 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Yoav Weiss (@Shopify) (Gerrit)

unread,
Jul 30, 2026, 7:23:46 AM (22 hours ago) Jul 30
to Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, Hiroki Nakagawa, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
Attention needed from Hiroki Nakagawa and Vladimir Levin

Yoav Weiss (@Shopify) added 5 comments

File third_party/blink/web_tests/TestExpectations
Line 3124, Patchset 11:# performance.getSpeculations().navigations reports the renderer's activated
Hiroki Nakagawa . resolved

Can you add a blank line between line 3123 and 3124?

Yoav Weiss (@Shopify)

Done

Line 3132, Patchset 11:crbug.com/532860179 virtual/speculation-rules-renderer-side-heuristics/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations.tentative.https.html [ Pass ]
Hiroki Nakagawa . resolved

Can you add a blank line between 3132 and 3133 to make the block clear?

Yoav Weiss (@Shopify)

Done

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
Line 45, Patchset 12: { source: 'list', urls: moderateUrls, eagerness: 'moderate' },
Hiroki Nakagawa . resolved

Can you remove this deprecated "source" param here and from other places in this file?

Yoav Weiss (@Shopify)

Done

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-pointerdown.tentative.https.html
Line 63, Patchset 12: source: 'document',
Hiroki Nakagawa . resolved

Ditto.

Yoav Weiss (@Shopify)

Done

File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
Line 92, Patchset 12: {source: 'list', urls: [barrierUrl], eagerness: 'immediate'},
Hiroki Nakagawa . resolved

Can you remove this deprecated "source" param?

Yoav Weiss (@Shopify)

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Hiroki Nakagawa
  • Vladimir Levin
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
    Gerrit-Change-Number: 8070441
    Gerrit-PatchSet: 13
    Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
    Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
    Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
    Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
    Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
    Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
    Gerrit-Attention: Hiroki Nakagawa <nhi...@chromium.org>
    Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
    Gerrit-Comment-Date: Thu, 30 Jul 2026 11:23:29 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Hiroki Nakagawa <nhi...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Hiroki Nakagawa (Gerrit)

    unread,
    Jul 30, 2026, 12:05:30 PM (18 hours ago) Jul 30
    to Yoav Weiss (@Shopify), Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
    Attention needed from Vladimir Levin and Yoav Weiss (@Shopify)

    Hiroki Nakagawa added 5 comments

    File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
    Line 40, Patchset 13 (Latest): // prefetch. Therefore navigations must NOT list them.
    Hiroki Nakagawa . unresolved

    IIUC, "navigations" here refers to `performance.getSpeculations().navigations`. Since it's a common term, could we either write it out fully as `performance.getSpeculations().navigations` or wrap it in backticks like \`navigations\`?

    This applies to other occurrences in this file.

    Line 83, Patchset 13 (Latest): // internal anchor at moderate eagerness — the Shopify-storefront shape.
    Hiroki Nakagawa . unresolved

    Can we remove this part?

    Line 174, Patchset 13 (Latest): { urls: [url], eagerness: 'immediate' },
    Hiroki Nakagawa . unresolved

    These are not aligned.

    File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
    Line 48, Patchset 13 (Latest):async function waitForNavigation(
    Hiroki Nakagawa . unresolved

    `waitForNavigation` sounds like this waits until completion of real navigation, but actually this just waits for speculation. Can we rename this to `waitForSpeculationMatching` or something like that?

    Line 78, Patchset 13 (Latest):// We use `immediate` (not `eager`) because `eager` is only fired
    // immediately when the kPreloadingEagerHoverHeuristics and
    // kPreloadingEagerViewportHeuristics features are both disabled; with
    // either enabled, `eager` candidates go to standby and never fire without
    // user gesture, which would deadlock the barrier.
    Hiroki Nakagawa . unresolved

    I think this comment is too specific to Chromium's internal implementation. I wonder if we could simply say something like, "We use immediate to immediately trigger the barrier ruleset"?

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Vladimir Levin
    • Yoav Weiss (@Shopify)
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
      Gerrit-Change-Number: 8070441
      Gerrit-PatchSet: 13
      Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
      Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
      Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
      Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
      Gerrit-CC: Nate Chapin <jap...@chromium.org>
      Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
      Gerrit-Attention: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
      Gerrit-Comment-Date: Thu, 30 Jul 2026 16:04:57 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Hiroki Nakagawa (Gerrit)

      unread,
      Jul 30, 2026, 12:06:08 PM (18 hours ago) Jul 30
      to Yoav Weiss (@Shopify), Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
      Attention needed from Vladimir Levin and Yoav Weiss (@Shopify)

      Hiroki Nakagawa voted and added 1 comment

      Votes added by Hiroki Nakagawa

      Code-Review+1

      1 comment

      Patchset-level comments
      File-level comment, Patchset 13 (Latest):
      Hiroki Nakagawa . resolved

      LGTM

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Vladimir Levin
      • Yoav Weiss (@Shopify)
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement satisfiedCode-Owners
      • requirement satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
      Gerrit-Change-Number: 8070441
      Gerrit-PatchSet: 13
      Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
      Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
      Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
      Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
      Gerrit-CC: Nate Chapin <jap...@chromium.org>
      Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
      Gerrit-Attention: Yoav Weiss (@Shopify) <yoav...@chromium.org>
      Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
      Gerrit-Comment-Date: Thu, 30 Jul 2026 16:05:41 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Yoav Weiss (@Shopify) (Gerrit)

      unread,
      Jul 30, 2026, 4:45:41 PM (13 hours ago) Jul 30
      to Hiroki Nakagawa, Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
      Attention needed from Vladimir Levin

      Yoav Weiss (@Shopify) added 6 comments

      Patchset-level comments
      File-level comment, Patchset 13:
      Yoav Weiss (@Shopify) . resolved

      Thanks for reviewing!!

      File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
      Line 40, Patchset 13: // prefetch. Therefore navigations must NOT list them.
      Hiroki Nakagawa . resolved

      IIUC, "navigations" here refers to `performance.getSpeculations().navigations`. Since it's a common term, could we either write it out fully as `performance.getSpeculations().navigations` or wrap it in backticks like \`navigations\`?

      This applies to other occurrences in this file.

      Yoav Weiss (@Shopify)

      Done

      Line 83, Patchset 13: // internal anchor at moderate eagerness — the Shopify-storefront shape.
      Hiroki Nakagawa . resolved

      Can we remove this part?

      Yoav Weiss (@Shopify)

      Sorry, missed this! done!

      Line 174, Patchset 13: { urls: [url], eagerness: 'immediate' },
      Hiroki Nakagawa . resolved

      These are not aligned.

      Yoav Weiss (@Shopify)

      Done

      File third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
      Line 48, Patchset 13:async function waitForNavigation(
      Hiroki Nakagawa . resolved

      `waitForNavigation` sounds like this waits until completion of real navigation, but actually this just waits for speculation. Can we rename this to `waitForSpeculationMatching` or something like that?

      Yoav Weiss (@Shopify)

      Done

      Line 78, Patchset 13:// We use `immediate` (not `eager`) because `eager` is only fired

      // immediately when the kPreloadingEagerHoverHeuristics and
      // kPreloadingEagerViewportHeuristics features are both disabled; with
      // either enabled, `eager` candidates go to standby and never fire without
      // user gesture, which would deadlock the barrier.
      Hiroki Nakagawa . resolved

      I think this comment is too specific to Chromium's internal implementation. I wonder if we could simply say something like, "We use immediate to immediately trigger the barrier ruleset"?

      Yoav Weiss (@Shopify)

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Vladimir Levin
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement satisfiedCode-Owners
        • requirement satisfiedCode-Review
        • requirement satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
        Gerrit-Change-Number: 8070441
        Gerrit-PatchSet: 13
        Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
        Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
        Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
        Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
        Gerrit-CC: Nate Chapin <jap...@chromium.org>
        Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
        Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
        Gerrit-Comment-Date: Thu, 30 Jul 2026 20:45:17 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        Comment-In-Reply-To: Hiroki Nakagawa <nhi...@chromium.org>
        satisfied_requirement
        open
        diffy

        Yoav Weiss (@Shopify) (Gerrit)

        unread,
        Jul 30, 2026, 4:45:56 PM (13 hours ago) Jul 30
        to Hiroki Nakagawa, Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, Chromium LUCI CQ, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org
        Attention needed from Vladimir Levin

        Yoav Weiss (@Shopify) voted Commit-Queue+2

        Commit-Queue+2
        Open in Gerrit

        Related details

        Attention is currently required from:
        • Vladimir Levin
        Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement satisfiedCode-Owners
        • requirement satisfiedCode-Review
        • requirement satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
        Gerrit-Change-Number: 8070441
        Gerrit-PatchSet: 14
        Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
        Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
        Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
        Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
        Gerrit-CC: Nate Chapin <jap...@chromium.org>
        Gerrit-CC: prerendering-reviews <prerenderi...@chromium.org>
        Gerrit-Attention: Vladimir Levin <vmp...@chromium.org>
        Gerrit-Comment-Date: Thu, 30 Jul 2026 20:45:37 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes
        satisfied_requirement
        open
        diffy

        Chromium LUCI CQ (Gerrit)

        unread,
        Jul 30, 2026, 6:53:03 PM (11 hours ago) Jul 30
        to Yoav Weiss (@Shopify), Hiroki Nakagawa, Nate Chapin, Blink W3C Test Autoroller, Vladimir Levin, AyeAye Python Dispatcher, android-bu...@system.gserviceaccount.com, chromium...@chromium.org, prerendering-reviews, gavinp...@chromium.org, tburkar...@chromium.org, gavin...@chromium.org, loading...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, core-timi...@chromium.org, gavinp+p...@chromium.org, speed-metrics...@chromium.org

        Chromium LUCI CQ submitted the change with unreviewed changes

        Unreviewed changes

        13 is the latest approved patch-set.
        The change was submitted with unreviewed changes in the following files:

        ```
        The name of the file: third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-preredirect-urls.tentative.https.html
        Insertions: 2, Deletions: 2.

        @@ -83,7 +83,7 @@

        // Wait for the browser to actually start the prefetch. The entry appears
        // in navigations at that point; polling avoids fixed-duration waits.
        - const preRedirectEntry = await waitForNavigation(t, redirectUrl);
        + const preRedirectEntry = await waitForSpeculationMatching(t, redirectUrl);
        assert_equals(preRedirectEntry.type, 'prefetch');
        assert_equals(preRedirectEntry.eagerness, 'immediate');

        @@ -107,7 +107,7 @@

        // Wait for the browser to actually create the prerender host. The entry
        // appears in navigations at that point.
        - const preRedirectEntry = await waitForNavigation(t, redirectUrl);
        + const preRedirectEntry = await waitForSpeculationMatching(t, redirectUrl);
        assert_equals(preRedirectEntry.type, 'prerender');

        const navigations = performance.getSpeculations().navigations;
        ```
        ```
        The name of the file: third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
        Insertions: 14, Deletions: 17.

        @@ -4,9 +4,9 @@
        // determine whether a speculative navigation has (or has not) been started.
        // Instead:
        // - For positive assertions ("this URL must appear in navigations"), poll
        -// performance.getSpeculations().navigations until the entry shows up,
        -// using `waitForNavigation`. Polling is state-driven — the test resumes
        -// as soon as the state flips.
        +// `performance.getSpeculations().navigations` until the entry shows up,
        +// using `waitForSpeculationMatching`. Polling is state-driven — the
        +// test resumes as soon as the state flips.
        // - For negative assertions ("this URL must NOT appear"), use a *barrier*:
        // add a known-eager candidate alongside the candidate under test in the
        // same rule set, wait for the barrier's entry to appear, and only then
        @@ -40,12 +40,12 @@
        .href;
        }

        -// Poll performance.getSpeculations().navigations until an entry matching
        +// Poll `performance.getSpeculations().navigations` until an entry matching
        // `predicate` appears. `predicate` may be a URL string (exact match) or a
        // callback receiving each entry.
        //
        // Returns the matching entry, or throws on the safety-net timeout.
        -async function waitForNavigation(
        +async function waitForSpeculationMatching(
        t, predicate, {timeoutMs = SPECULATION_POLL_SAFETY_MS} = {}) {
        const match =
        typeof predicate === 'string' ? (n => n.url === predicate) : predicate;
        @@ -66,20 +66,17 @@

        // Barrier-based synchronization for negative assertions.
        //
        -// The browser processes each SpeculationHost::UpdateSpeculationCandidates
        -// message atomically: all candidates in one rule set are consumed together.
        -// So if we insert a rule set containing one URL under test PLUS an
        -// `immediate`-eagerness "barrier" URL, and we then wait until the barrier
        -// appears in navigations, we know the browser has had time to enact
        -// anything else it was going to enact from that same rule set. If the URL
        +// The browser processes each rule set atomically: all of its candidates are
        +// consumed together. So if we insert a rule set containing one URL under test
        +// PLUS an `immediate`-eagerness "barrier" URL, and we then wait until the
        +// barrier appears in `performance.getSpeculations().navigations`, we know the
        +// browser has had time to enact anything else it was going to enact from that
        +// same rule set. If the URL
        // under test is still absent, it's absent because the browser chose not to
        // enact it — which is exactly what the negative assertion is checking.
        //
        -// We use `immediate` (not `eager`) because `eager` is only fired
        -// immediately when the kPreloadingEagerHoverHeuristics and
        -// kPreloadingEagerViewportHeuristics features are both disabled; with
        -// either enabled, `eager` candidates go to standby and never fire without
        -// user gesture, which would deadlock the barrier.
        +// We use `immediate` to trigger the barrier immediately, without needing any
        +// user interaction.
        //
        // Returns { barrierUrl, ruleSet } so the caller can insert the rule set
        // with insertSpeculationRules(ruleSet) and later verify via
        @@ -99,7 +96,7 @@
        // navigations array. Any URL still absent at this point is absent because
        // the browser decided not to enact it, not because of timing.
        async function awaitBarrierAndSnapshot(t, barrierUrl) {
        - await waitForNavigation(t, barrierUrl);
        + await waitForSpeculationMatching(t, barrierUrl);
        return performance.getSpeculations().navigations;
        }

        ```
        ```
        The name of the file: third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
        Insertions: 29, Deletions: 19.

        @@ -11,7 +11,7 @@
        <script src="support/speculation-measurement-utils.js"></script>
        <body>
        <script>
        -// performance.getSpeculations().navigations reports the speculative
        +// `performance.getSpeculations().navigations` reports the speculative
        // navigations that the browser has actually started, not the set of
        // candidates a site has proposed. These tests exercise that filtering per
        // eagerness level:
        @@ -23,7 +23,8 @@
        // - once the user interacts with a link that matches the rule, the
        // corresponding entry SHOULD appear.
        //
        -// Synchronization: all subtests use polling (waitForNavigation) or barrier
        +// Synchronization: all subtests use polling (waitForSpeculationMatching) or
        +// barrier
        // synchronization (awaitBarrierAndSnapshot) — never fixed-duration
        // timeouts — so they are fast when the state flips quickly and robust on
        // slow bots.
        @@ -37,7 +38,8 @@
        promise_test(async t => {
        // A single moderate-eagerness prefetch rule listing many URLs. Without
        // any user interaction, the browser parks these on-standby and does NOT
        - // prefetch. Therefore navigations must NOT list them.
        + // prefetch. Therefore `performance.getSpeculations().navigations` must NOT
        + // list them.
        const moderateUrls = Array.from({length: 10},
        (_, i) => uniqueNavigationUrl(`moderate-no-interaction-${i}`));

        @@ -51,10 +53,12 @@
        const matches = navsAfterBarrier
        .filter(n => moderateUrls.includes(n.url));
        assert_equals(matches.length, 0,
        - "moderate-eagerness candidates must NOT appear in navigations before " +
        + "moderate-eagerness candidates must NOT appear in " +
        + "`performance.getSpeculations().navigations` before " +
        "any user interaction triggers them (got: " +
        matches.map(m => m.url).join(", ") + ")");
        -}, "Moderate-eagerness prefetch rule alone does not populate navigations");
        +}, "Moderate-eagerness prefetch rule alone does not populate " +
        + "`performance.getSpeculations().navigations`");

        promise_test(async t => {
        // Same shape, but conservative eagerness. Conservative candidates only
        @@ -73,15 +77,16 @@
        const matches = navsAfterBarrier
        .filter(n => conservativeUrls.includes(n.url));
        assert_equals(matches.length, 0,
        - "conservative-eagerness candidates must NOT appear in navigations " +
        + "conservative-eagerness candidates must NOT appear in " +
        + "`performance.getSpeculations().navigations` " +
        "before pointerdown triggers them");
        }, "Conservative-eagerness prefetch rule alone does not populate " +
        - "navigations");
        + "`performance.getSpeculations().navigations`");

        promise_test(async t => {
        // A document-source rule with a `where` predicate that matches every
        - // internal anchor at moderate eagerness — the Shopify-storefront shape.
        - // No user interaction. navigations must NOT include any of these.
        + // internal anchor at moderate eagerness. No user interaction, so
        + // `performance.getSpeculations().navigations` must NOT include any of these.
        const targetUrls = Array.from({length: 5},
        (_, i) => uniqueNavigationUrl(`doc-rule-moderate-${i}`));

        @@ -115,11 +120,12 @@
        const matches = navsAfterBarrier
        .filter(n => targetUrls.includes(n.url));
        assert_equals(matches.length, 0,
        - "moderate document-source candidates must NOT appear in navigations " +
        + "moderate document-source candidates must NOT appear in " +
        + "`performance.getSpeculations().navigations` " +
        "before user interaction (got: " + matches.map(m => m.url).join(", ") +
        ")");
        }, "Moderate document-source prefetch rule with anchors does not populate " +
        - "navigations without user interaction");
        + "`performance.getSpeculations().navigations` without user interaction");

        promise_test(async t => {
        // Mixed rule set: two URLs at eager eagerness (should appear) and two at
        @@ -127,7 +133,8 @@
        // per-candidate, not per-ruleset.
        //
        // The immediate URLs themselves serve as the barrier: once both are in
        - // navigations, the browser has finished with this rule set.
        + // `performance.getSpeculations().navigations`, the browser has finished with
        + // this rule set.
        const immediateUrls = [
        uniqueNavigationUrl('mixed-immediate-0'),
        uniqueNavigationUrl('mixed-immediate-1'),
        @@ -144,14 +151,16 @@
        ]
        });

        - // Wait for both immediate URLs to land in navigations.
        - await Promise.all(immediateUrls.map(u => waitForNavigation(t, u)));
        + // Wait for both immediate URLs to land in
        + // `performance.getSpeculations().navigations`.
        + await Promise.all(immediateUrls.map(u => waitForSpeculationMatching(t, u)));

        const data = performance.getSpeculations();
        const moderateMatches = data.navigations
        .filter(n => moderateUrls.includes(n.url));
        assert_equals(moderateMatches.length, 0,
        - "moderate-eagerness URLs must NOT appear in navigations even after " +
        + "moderate-eagerness URLs must NOT appear in " +
        + "`performance.getSpeculations().navigations` even after " +
        "sibling immediate-eagerness URLs from the same rule set have been " +
        "enacted (got: " + moderateMatches.map(m => m.url).join(", ") + ")");
        }, "Mixed eagerness rule: only immediate candidates appear, not moderate");
        @@ -165,18 +174,18 @@
        promise_test(async t => {
        // Only unique candidates count. If a rule declares the same URL twice, or
        // two rules declare the same URL, the URL should appear at most once in
        - // navigations for a given action.
        + // `performance.getSpeculations().navigations` for a given action.
        const url = uniqueNavigationUrl('dedup-test');

        insertSpeculationRules({
        prefetch: [
        { urls: [url, url], eagerness: 'immediate' },
        - { urls: [url], eagerness: 'immediate' },
        + { urls: [url], eagerness: 'immediate' },
        ]
        });

        // Wait for the URL to appear at least once.
        - await waitForNavigation(t, url);
        + await waitForSpeculationMatching(t, url);

        // Then use a barrier via a fresh rule set to give any hypothetical
        // extra-notification more time to arrive before we count.
        @@ -188,6 +197,7 @@
        assert_less_than_equal(matches.length, 1,
        "duplicate declarations of the same (url, action) collapse to one " +
        "navigation entry (got " + matches.length + ")");
        -}, "navigations deduplicates (url, action) across duplicate declarations");
        +}, "`performance.getSpeculations().navigations` deduplicates (url, action) " +
        + "across duplicate declarations");
        </script>
        </body>
        ```
        ```
        The name of the file: third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-pointerdown.tentative.https.html
        Insertions: 1, Deletions: 1.

        @@ -90,7 +90,7 @@
        .send();

        // Poll for the entry to show up.
        - const nav = await waitForNavigation(t, url);
        + const nav = await waitForSpeculationMatching(t, url);
        assert_equals(nav.eagerness, 'conservative',
        "reported eagerness must be the declared eagerness");
        assert_equals(nav.type, 'prefetch',
        ```
        ```
        The name of the file: third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations.tentative.https.html
        Insertions: 12, Deletions: 11.

        @@ -49,7 +49,7 @@
        }]
        });

        - const nav = await waitForNavigation(t, prefetchUrl);
        + const nav = await waitForSpeculationMatching(t, prefetchUrl);
        assert_equals(nav.type, "prefetch", "type should be 'prefetch'");
        assert_equals(nav.url, prefetchUrl, "url should match");
        assert_equals(nav.eagerness, "immediate",
        @@ -69,7 +69,7 @@
        }]
        });

        - const nav = await waitForNavigation(t, prefetchUrl);
        + const nav = await waitForSpeculationMatching(t, prefetchUrl);
        assert_true(Array.isArray(nav.tags), "tags should be an array");
        assert_true(nav.tags.includes('my-tag'),
        "tags should include the specified tag");
        @@ -86,7 +86,7 @@
        }]
        });

        - const nav = await waitForNavigation(t, prefetchUrl);
        + const nav = await waitForSpeculationMatching(t, prefetchUrl);
        assert_equals(nav.tags, null, "tags should be null when not specified");
        }, "Navigation without tags has null tags");

        @@ -98,9 +98,9 @@

        promise_test(async t => {
        // A moderate-eagerness prefetch rule alone (no user interaction, no
        - // pointerdown, no hover) must NOT populate `navigations`, because the
        - // browser only parks such candidates on-standby and never prefetches
        - // them.
        + // pointerdown, no hover) must NOT populate
        + // `performance.getSpeculations().navigations`, because the browser only parks
        + // such candidates on-standby and never prefetches them.
        //
        // Synchronization: include an eager barrier URL in the same rule set.
        // Once the barrier appears in navigations, we know the browser has
        @@ -140,7 +140,7 @@
        });
        document.head.appendChild(script);

        - await waitForNavigation(t, prefetchUrl);
        + await waitForSpeculationMatching(t, prefetchUrl);

        // Remove the speculation rules script element.
        script.remove();
        @@ -162,8 +162,9 @@
        // prefetched at eager eagerness; both entries should end up in
        // navigations even though only one rule set is active at any time.
        //
        - // `navigations` accumulates across rule replacement for distinct URLs.
        - // Same-URL declarations dedup by (url, action).
        + // `performance.getSpeculations().navigations` accumulates across rule
        + // replacement for distinct URLs. Same-URL declarations dedup by
        + // (url, action).
        const firstUrl = uniqueNavigationUrl('replace-first');
        const secondUrl = uniqueNavigationUrl('replace-second');

        @@ -174,7 +175,7 @@
        });
        document.head.appendChild(script1);

        - await waitForNavigation(t, firstUrl);
        + await waitForSpeculationMatching(t, firstUrl);

        // Swap rule sets: remove the first, add a rule for a different URL.
        script1.remove();
        @@ -187,7 +188,7 @@
        document.head.appendChild(script2);
        t.add_cleanup(() => script2.remove());

        - await waitForNavigation(t, secondUrl);
        + await waitForSpeculationMatching(t, secondUrl);

        // Both entries should coexist.
        const data = performance.getSpeculations();
        ```

        Change information

        Commit message:
        Speculation measurement - renderer source of truth

        After having moved the speculation rules heuristics to the renderer,
        this CL moves the speculation rules measurement to be based on these
        renderer-side heuristics.
        Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
        Bug: 532860179
        Commit-Queue: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Reviewed-by: Hiroki Nakagawa <nhi...@chromium.org>
        Cr-Commit-Position: refs/heads/main@{#1671486}
        Files:
        • M content/browser/preloading/preloading_decider_unittest.cc
        • M third_party/blink/renderer/core/loader/anchor_element_interaction_test.cc
        • M third_party/blink/renderer/core/speculation_rules/document_speculation_rules.cc
        • M third_party/blink/renderer/core/speculation_rules/document_speculation_rules.h
        • M third_party/blink/renderer/core/speculation_rules/stub_speculation_host.h
        • M third_party/blink/renderer/core/timing/window_performance.cc
        • M third_party/blink/web_tests/TestExpectations
        • M third_party/blink/web_tests/VirtualTestSuites
        • A third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-eagerness.tentative.https.html
        • A third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations-pointerdown.tentative.https.html
        • M third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-navigations.tentative.https.html
        • M third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/performance-speculations-preredirect-urls.tentative.https.html
        • M third_party/blink/web_tests/external/wpt/speculation-rules/speculation-measurement/support/speculation-measurement-utils.js
        Change size: L
        Delta: 13 files changed, 661 insertions(+), 118 deletions(-)
        Branch: refs/heads/main
        Submit Requirements:
        • requirement satisfiedCode-Review: +1 by Hiroki Nakagawa
        Open in Gerrit
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: merged
        Gerrit-Project: chromium/src
        Gerrit-Branch: main
        Gerrit-Change-Id: Ifef5dd8548285f03aa87ddbb9da3840e64b406ad
        Gerrit-Change-Number: 8070441
        Gerrit-PatchSet: 15
        Gerrit-Owner: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-Reviewer: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
        Gerrit-Reviewer: Hiroki Nakagawa <nhi...@chromium.org>
        Gerrit-Reviewer: Vladimir Levin <vmp...@chromium.org>
        Gerrit-Reviewer: Yoav Weiss (@Shopify) <yoav...@chromium.org>
        Gerrit-CC: AyeAye Python Dispatcher <android-build-ayeay...@system.gserviceaccount.com>
        Gerrit-CC: Blink W3C Test Autoroller <blink-w3c-te...@chromium.org>
        open
        diffy
        satisfied_requirement
        Reply all
        Reply to author
        Forward
        0 new messages