[soft-navs] SoftNavigationContext created in terms of Interactions. [chromium/src : main]

0 views
Skip to first unread message

Michal Mocny (Gerrit)

unread,
Mar 5, 2026, 7:46:58 PMMar 5
to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
Attention needed from Scott Haseley

Michal Mocny voted Commit-Queue+1

Commit-Queue+1
Open in Gerrit

Related details

Attention is currently required from:
  • Scott Haseley
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: I32c2c09584340e17b9b7707650041eda6a6a6964
Gerrit-Change-Number: 7638455
Gerrit-PatchSet: 4
Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
Gerrit-CC: Nate Chapin <jap...@chromium.org>
Gerrit-Attention: Scott Haseley <shas...@chromium.org>
Gerrit-Comment-Date: Fri, 06 Mar 2026 00:46:51 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
satisfied_requirement
unsatisfied_requirement
open
diffy

Scott Haseley (Gerrit)

unread,
Mar 5, 2026, 11:57:53 PMMar 5
to Michal Mocny, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
Attention needed from Michal Mocny

Scott Haseley added 19 comments

Patchset-level comments
File-level comment, Patchset 5 (Latest):
Scott Haseley . resolved

This looks quite reasonable, but I need to read SNH again with a fresh brain in the morning. Some of the failed tests / crashes look interesting, but I didn't look into them.

File third_party/blink/renderer/core/events/pop_state_event.h
Line 90, Patchset 5 (Latest): const PerformanceTimelineEntryIdInfo interaction_id_ =
Scott Haseley . unresolved

I know it's rather innocuous having this, but I think it would be better to push this to the patch it's used in, unless you can do a stack and you think we'll get them both in before branch. Same for HashChangeEvent.

File third_party/blink/renderer/core/frame/history.cc
Line 401, Patchset 5 (Latest): /*is_browser_initiated=*/false, /*is_synchronously_committed=*/true);
Scott Haseley . unresolved

Are these needed or should can they continue using the default values?

File third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
Line 1510, Patchset 5 (Latest): /*is_synchronously_committed=*/true);
Scott Haseley . unresolved

Is this needed, or should it just continue using the default value?

File third_party/blink/renderer/core/navigation_api/navigation_api.cc
Line 868, Patchset 5 (Latest): if (auto id = event_timing_scope.GetInteractionIdInfo()) {
Scott Haseley . unresolved

style nit: this might be clearer without auto since the type isn't obvious
(see https://google.github.io/styleguide/cppguide.html#Type_deduction).

File third_party/blink/renderer/core/timing/soft_navigation_context.cc
Line 41, Patchset 5 (Latest): CHECK(entry);
CHECK(entry->IsKnownToBeAnInteraction());
Scott Haseley . unresolved

Should these checks also be applied to the `initial_event_timing_`?

Line 277, Patchset 5 (Latest): uint64_t interaction_id = initial_event_timing_->interactionId();
Scott Haseley . unresolved

nit: consider inlining below since this is only used once.

Line 307, Patchset 5 (Latest): CHECK(window_);
Scott Haseley . unresolved

Why move these up? FWIW I had the CHECK(window_) below the flag check because I didn't want the check to fail in prod without the feature enabled.

Line 315, Patchset 5 (Latest): uint64_t interaction_id = initial_event_timing_->interactionId();
Scott Haseley . unresolved

nit: same here - consider inlining below since this is only used once.

File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
Line 167, Patchset 5 (Parent): if (!event.IsFullyTrusted()) {
return std::nullopt;
}
Scott Haseley . unresolved

Do we lose this check? I think this is problematic since that was added to fix a crash / unexpected behavior for creating contexts during simulated events.

Line 209, Patchset 5 (Latest): if (context) {
Scott Haseley . unresolved

How can this be null? Entries should be automatically removed by GC and never null.

Line 227, Patchset 5 (Latest): // is tracking it. If the context comes from a task that crossed from
// another, we might have a different SNH instance. This seems to fail
Scott Haseley . unresolved

nit: removing "created in one window" makes sound unclear to me now.

Line 234, Patchset 5 (Latest): for (const auto& tracked_context : interaction_id_to_context_.Values()) {
Scott Haseley . unresolved

I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

Line 292, Patchset 5 (Latest): SoftNavigationContext* context_for_task =
Scott Haseley . unresolved

Move above line 287 and use that in the ternary expression?

Line 454, Patchset 5 (Latest): if (context && context->OnPaintFinished()) {
Scott Haseley . unresolved

I don't think this can be null

Line 586, Patchset 5 (Latest): TRACE_EVENT_BEGIN("loading", "SoftNavigation",
Scott Haseley . unresolved

We really should move this into SNC...

File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.h
Line 17, Patchset 5 (Latest):class PerformanceEventTiming;
Scott Haseley . unresolved

nit: merge with other forward declarations above.

File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.cc
Line 30, Patchset 5 (Latest): reporting_info.processing_end_time = start_time;
Scott Haseley . unresolved

Worth giving this some kind of duration?

Line 35, Patchset 5 (Latest): /*navigation_id=*/1, PerformanceTimelineEntryIdInfo(1, 1));
Scott Haseley . unresolved

We could also, not necessarily now, make a base class for tests with an id generator member and this as a method, and each interaction could use this (or use the same ID via a "should_increment" parameter or something).

Open in Gerrit

Related details

Attention is currently required from:
  • Michal Mocny
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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 5
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 04:57:43 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 6:49:38 AMMar 6
    to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny added 16 comments

    Patchset-level comments
    Michal Mocny . resolved

    Ty for review!

    Replies first, will work on addressing these next...

    File third_party/blink/renderer/core/events/pop_state_event.h
    Line 90, Patchset 5 (Latest): const PerformanceTimelineEntryIdInfo interaction_id_ =
    Scott Haseley . unresolved

    I know it's rather innocuous having this, but I think it would be better to push this to the patch it's used in, unless you can do a stack and you think we'll get them both in before branch. Same for HashChangeEvent.

    Michal Mocny

    Sg. This was more of an "initial direction" that proved unneeded.

    File third_party/blink/renderer/core/frame/history.cc
    Line 401, Patchset 5 (Latest): /*is_browser_initiated=*/false, /*is_synchronously_committed=*/true);
    Scott Haseley . unresolved

    Are these needed or should can they continue using the default values?

    Michal Mocny

    good eye-- I had added interaction_id to last param initially, then switched the order specifically to get to do that-- but forgot to make this change :P

    File third_party/blink/renderer/core/timing/soft_navigation_context.h
    Line 74, Patchset 5 (Latest): // Soft LCP. It is the startTime of the last event timing entry before first
    // paint.
    Michal Mocny . unresolved

    this changed. It is now first event timing.

    Pray I do not change it further :)

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 41, Patchset 5 (Latest): CHECK(entry);
    CHECK(entry->IsKnownToBeAnInteraction());
    Scott Haseley . unresolved

    Should these checks also be applied to the `initial_event_timing_`?

    Michal Mocny

    In the constructor? Good idea!

    Line 277, Patchset 5 (Latest): uint64_t interaction_id = initial_event_timing_->interactionId();
    Scott Haseley . unresolved

    nit: consider inlining below since this is only used once.

    Michal Mocny

    I added `GetInteractionIdInfo` to this class specifically so I wouldn't need to hard-code things like this here, but missed this one. ty

    Scott Haseley . unresolved

    Why move these up? FWIW I had the CHECK(window_) below the flag check because I didn't want the check to fail in prod without the feature enabled.

    Michal Mocny

    Oh I thought SoftNavigationHeuristicsEnabled needed `window_` and so moved up... ty for noticing

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 167, Patchset 5 (Parent): if (!event.IsFullyTrusted()) {
    return std::nullopt;
    }
    Scott Haseley . unresolved

    Do we lose this check? I think this is problematic since that was added to fix a crash / unexpected behavior for creating contexts during simulated events.

    Michal Mocny

    I can add the check back, but my expectation was that this check was part of the mini-interaction-event-scope machinery that SNH tried to minic and is being wholesale replaced.

    I didn't think that ICP should apply to a subset of Interactions only, and that all the semantics should be up in Event Timing.

    So, if this indeed still fails, I think it would be better to move up to the Event Timing scope and prevent such events from being Interactions.

    ---

    You mention this applies to simulated events-- if you mean web automation tools, then maybe we need to keep allowing Event TIming to measure those, but should just turn off the context and leave here.

    If you mean real user simulated events, if there is some gap where event timing isn't filtering enough, then we certainly should move up there.

    WDYT?

    Line 227, Patchset 5 (Latest): // is tracking it. If the context comes from a task that crossed from
    // another, we might have a different SNH instance. This seems to fail
    Scott Haseley . unresolved

    nit: removing "created in one window" makes sound unclear to me now.

    Michal Mocny

    sg.

    I wonder if EnsureContextForCurrentWindow should just be folded into GetSoftNavigationContextForCurrentTask() now that we don't pass context* around?

    The only other call site is `ReportSoftNavigationToMetrics` but that is already after we emit to perf timeline and have a whole bunch of effects, so probably not needed there.

    (Ill leave for this patch)

    Line 234, Patchset 5 (Latest): for (const auto& tracked_context : interaction_id_to_context_.Values()) {
    Scott Haseley . unresolved

    I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

    Michal Mocny

    Let me see if understand what you mean:

    • A task can become scheduled on a window
    • That task might have state which has a context*
    • That task might modify dom (etc) and call into SNH static members
    • Now we need to check, which can be expensive, if this SNH map for *this* window was *the* window for this context

    But if we just stored the back pointer from SNC to SNC we could just check directly on the one context.

    SGTM.

    Line 245, Patchset 5 (Latest): uint64_t interaction_id) const {
    Michal Mocny . unresolved

    TODO: try to pass the full typed struct where possible.

    Line 292, Patchset 5 (Latest): SoftNavigationContext* context_for_task =
    Scott Haseley . unresolved

    Move above line 287 and use that in the ternary expression?

    Michal Mocny

    sg, originally I didnt even have this but some of the tests failed because I made mistakes while setting them up so added this guard. It will be possible to remove completely, I just wanted to check the try-bots with it. Should have left a comment.

    I could also leave this in, but add NotFatal? since the worst effect of this getting wrong is that we assign the wrong id/starttime to the wrong context. We should know, but maybe not worth crashing.

    Line 586, Patchset 5 (Latest): TRACE_EVENT_BEGIN("loading", "SoftNavigation",
    Scott Haseley . unresolved

    We really should move this into SNC...

    Michal Mocny

    I can do that. I think there are a few other reporting things in here that could, but I'll limit the moves for now.

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.cc
    Line 30, Patchset 5 (Latest): reporting_info.processing_end_time = start_time;
    Scott Haseley . unresolved

    Worth giving this some kind of duration?

    Michal Mocny

    Yeah. Even better would be to merge the Utils that window_performance_test.cc uses (which has a lot more careful setup of invarients and simulation for lifecycle)...

    Might have to move/rename util files around, but for now I think I'll just duplicate the code.

    Line 35, Patchset 5 (Latest): /*navigation_id=*/1, PerformanceTimelineEntryIdInfo(1, 1));
    Michal Mocny . unresolved

    (From AI reviewer:)

    Hardcoding the interaction ID to (1, 1) can lead to incorrect test behavior. For example, in `SoftNavigationHeuristicsTest.HeuristicNotResetDuringGCWithActiveContext`, two separate click events are simulated, but they will end up with the same interaction ID and reuse the same `SoftNavigationContext`, which is likely not the intent.

    Consider using an ID generator here, or passing the ID in as a parameter, similar to the fix in `InteractionEffectsMonitorTest`.

    Line 35, Patchset 5 (Latest): /*navigation_id=*/1, PerformanceTimelineEntryIdInfo(1, 1));
    Scott Haseley . resolved

    We could also, not necessarily now, make a base class for tests with an id generator member and this as a method, and each interaction could use this (or use the same ID via a "should_increment" parameter or something).

    Michal Mocny

    I think that the InteractionID Unittest base in window_performance_test.cc does some of this and probably the soft nav / icp tests should eventually become a subclass of that... But yeah, larger test refactor for later.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 5
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 11:49:31 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Scott Haseley <shas...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 7:01:26 AMMar 6
    to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny added 1 comment

    Patchset-level comments
    Michal Mocny . resolved

    Also, found the bug that caused tests to crash:

    I added `PerformanceEventTiming::IsKnownToBeAnInteraction` but theres a subtle bug: some interactions which have an id>0 are "ignored" and treated as 0 anyway-- like autoscroll, which is where the tests were failing.

    We were accidentally trying to create context with id==0 which the hashmap didn't like using as a key. Good catch, bots!

    (There autoscroll are distinct from gesture scroll, which we wont count for different reasons)

    Gerrit-Comment-Date: Fri, 06 Mar 2026 12:01:18 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 8:27:08 AMMar 6
    to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny added 1 comment

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 234, Patchset 5: for (const auto& tracked_context : interaction_id_to_context_.Values()) {
    Scott Haseley . unresolved

    I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

    Michal Mocny

    Let me see if understand what you mean:

    • A task can become scheduled on a window
    • That task might have state which has a context*
    • That task might modify dom (etc) and call into SNH static members
    • Now we need to check, which can be expensive, if this SNH map for *this* window was *the* window for this context

    But if we just stored the back pointer from SNC to SNC we could just check directly on the one context.

    SGTM.

    Michal Mocny

    I added this, because I think its useful to have a backpointer... but I noticed that SNC already has a window_ and I think we can get SNH from window_, and the goal is to check for this window is the original window... I think

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 6
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 13:27:00 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Scott Haseley <shas...@chromium.org>
    Comment-In-Reply-To: Michal Mocny <mmo...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 11:17:15 AMMar 6
    to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny added 17 comments

    File third_party/blink/renderer/core/frame/history.cc
    Line 401, Patchset 5: /*is_browser_initiated=*/false, /*is_synchronously_committed=*/true);
    Scott Haseley . resolved

    Are these needed or should can they continue using the default values?

    Michal Mocny

    good eye-- I had added interaction_id to last param initially, then switched the order specifically to get to do that-- but forgot to make this change :P

    Michal Mocny

    Done

    File third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
    Line 1510, Patchset 5: /*is_synchronously_committed=*/true);
    Scott Haseley . resolved

    Is this needed, or should it just continue using the default value?

    Michal Mocny

    Done

    File third_party/blink/renderer/core/navigation_api/navigation_api.cc
    Line 868, Patchset 5: if (auto id = event_timing_scope.GetInteractionIdInfo()) {
    Scott Haseley . resolved

    style nit: this might be clearer without auto since the type isn't obvious
    (see https://google.github.io/styleguide/cppguide.html#Type_deduction).

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_context.h
    Line 74, Patchset 5: // Soft LCP. It is the startTime of the last event timing entry before first
    // paint.
    Michal Mocny . resolved

    this changed. It is now first event timing.

    Pray I do not change it further :)

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 41, Patchset 5: CHECK(entry);
    CHECK(entry->IsKnownToBeAnInteraction());
    Scott Haseley . resolved

    Should these checks also be applied to the `initial_event_timing_`?

    Michal Mocny

    In the constructor? Good idea!

    Michal Mocny

    Done

    Line 269, Patchset 6 (Parent): // `heuristics` will be null if the `window_` was detached but this context
    Michal Mocny . unresolved

    restore this

    Line 277, Patchset 5: uint64_t interaction_id = initial_event_timing_->interactionId();
    Scott Haseley . resolved

    nit: consider inlining below since this is only used once.

    Michal Mocny

    I added `GetInteractionIdInfo` to this class specifically so I wouldn't need to hard-code things like this here, but missed this one. ty

    Michal Mocny

    Done

    Line 307, Patchset 5: CHECK(window_);
    Scott Haseley . resolved

    Why move these up? FWIW I had the CHECK(window_) below the flag check because I didn't want the check to fail in prod without the feature enabled.

    Michal Mocny

    Oh I thought SoftNavigationHeuristicsEnabled needed `window_` and so moved up... ty for noticing

    Michal Mocny

    Done

    Line 315, Patchset 5: uint64_t interaction_id = initial_event_timing_->interactionId();
    Scott Haseley . resolved

    nit: same here - consider inlining below since this is only used once.

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 209, Patchset 5: if (context) {
    Scott Haseley . resolved

    How can this be null? Entries should be automatically removed by GC and never null.

    Michal Mocny

    Done

    Line 227, Patchset 5: // is tracking it. If the context comes from a task that crossed from

    // another, we might have a different SNH instance. This seems to fail
    Scott Haseley . resolved

    nit: removing "created in one window" makes sound unclear to me now.

    Michal Mocny

    sg.

    I wonder if EnsureContextForCurrentWindow should just be folded into GetSoftNavigationContextForCurrentTask() now that we don't pass context* around?

    The only other call site is `ReportSoftNavigationToMetrics` but that is already after we emit to perf timeline and have a whole bunch of effects, so probably not needed there.

    (Ill leave for this patch)

    Michal Mocny

    After the change to the "hot path" check for SNH, this function became a one liner-- so I just inlined it and remvoed it.

    Line 234, Patchset 5: for (const auto& tracked_context : interaction_id_to_context_.Values()) {
    Scott Haseley . resolved

    I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

    Michal Mocny

    Let me see if understand what you mean:

    • A task can become scheduled on a window
    • That task might have state which has a context*
    • That task might modify dom (etc) and call into SNH static members
    • Now we need to check, which can be expensive, if this SNH map for *this* window was *the* window for this context

    But if we just stored the back pointer from SNC to SNC we could just check directly on the one context.

    SGTM.

    Michal Mocny

    I added this, because I think its useful to have a backpointer... but I noticed that SNC already has a window_ and I think we can get SNH from window_, and the goal is to check for this window is the original window... I think

    Michal Mocny

    Done

    Line 245, Patchset 5: uint64_t interaction_id) const {
    Michal Mocny . resolved

    TODO: try to pass the full typed struct where possible.

    Michal Mocny

    Done

    Line 454, Patchset 5: if (context && context->OnPaintFinished()) {
    Scott Haseley . resolved

    I don't think this can be null

    Michal Mocny

    Done

    Line 586, Patchset 5: TRACE_EVENT_BEGIN("loading", "SoftNavigation",
    Scott Haseley . resolved

    We really should move this into SNC...

    Michal Mocny

    I can do that. I think there are a few other reporting things in here that could, but I'll limit the moves for now.

    Michal Mocny

    I moved a small amount of tracing now, but added a comment to the crbug to followup

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.h
    Line 17, Patchset 5:class PerformanceEventTiming;
    Scott Haseley . resolved

    nit: merge with other forward declarations above.

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.cc
    Line 30, Patchset 5: reporting_info.processing_end_time = start_time;
    Scott Haseley . resolved

    Worth giving this some kind of duration?

    Michal Mocny

    Yeah. Even better would be to merge the Utils that window_performance_test.cc uses (which has a lot more careful setup of invarients and simulation for lifecycle)...

    Might have to move/rename util files around, but for now I think I'll just duplicate the code.

    Michal Mocny

    fixed a small amount here, but added comment to crbug to followup with a larger unification here.

    Gerrit-Comment-Date: Fri, 06 Mar 2026 16:17:10 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Mar 6, 2026, 11:28:36 AMMar 6
    to Michal Mocny, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org

    Scott Haseley added 4 comments

    Patchset-level comments
    File-level comment, Patchset 6 (Latest):
    Scott Haseley . resolved

    Still catching up. Brain-dumping my sleep thoughts before I grab breakfast.

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 167, Patchset 5 (Parent): if (!event.IsFullyTrusted()) {
    return std::nullopt;
    }
    Scott Haseley . unresolved

    Do we lose this check? I think this is problematic since that was added to fix a crash / unexpected behavior for creating contexts during simulated events.

    Michal Mocny

    I can add the check back, but my expectation was that this check was part of the mini-interaction-event-scope machinery that SNH tried to minic and is being wholesale replaced.

    I didn't think that ICP should apply to a subset of Interactions only, and that all the semantics should be up in Event Timing.

    So, if this indeed still fails, I think it would be better to move up to the Event Timing scope and prevent such events from being Interactions.

    ---

    You mention this applies to simulated events-- if you mean web automation tools, then maybe we need to keep allowing Event TIming to measure those, but should just turn off the context and leave here.

    If you mean real user simulated events, if there is some gap where event timing isn't filtering enough, then we certainly should move up there.

    WDYT?

    Scott Haseley

    The problem was simulated event (untrusted) causing a trusted event. This happens because of form controls. See https://chromium-review.googlesource.com/c/chromium/src/+/7466724 (if you're passing that test, this might be okay now)

    Line 234, Patchset 5: for (const auto& tracked_context : interaction_id_to_context_.Values()) {
    Scott Haseley . unresolved

    I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

    Michal Mocny

    Let me see if understand what you mean:

    • A task can become scheduled on a window
    • That task might have state which has a context*
    • That task might modify dom (etc) and call into SNH static members
    • Now we need to check, which can be expensive, if this SNH map for *this* window was *the* window for this context

    But if we just stored the back pointer from SNC to SNC we could just check directly on the one context.

    SGTM.

    Michal Mocny

    I added this, because I think its useful to have a backpointer... but I noticed that SNC already has a window_ and I think we can get SNH from window_, and the goal is to check for this window is the original window... I think

    Scott Haseley

    Thought of that at 4AM in my sleep too... Yeah I think we can just check context->GetWindow() == Window() (making these up). That was why this was added IIRC (cross-window main frame case w/ window.opener()).

    If we want to (eventually) exclude other contexts (e.g. if we shutdown early), we can check if they've been shutdown or whatever.

    Line 578, Patchset 6 (Latest): SoftNavigationContext* context = GetRelevantContext(interaction_id);
    Scott Haseley . unresolved

    Since the map holds WeakMember<context>, I think there's an edge case where we can create multiple contexts for the same interaction_id. Not sure if you thought about this? I think most won't matter in practice, but the retainer dependency is a bit gnarly (it relies on the paint attribution tracker to manage lifetime).

    Okay example:
    - keydown
    - dom update
    - paint tracker holds strong reference
    - keyup
    finds context
    Benign example:
    - keydown, create context
    - keydown does nothing
    - GC happens -- context GCed
    - keyup
    - new context
    Edge case:
    - keydown, create context; hold key (same can happen once pointer down gets id)
    - update some dom
    - paint
    - emit ICP
    - ...
    - remove said updated dom
    - GC
    - context GCed because no more retainers
    - keyup
    - no matching context for id, new context
    Open in Gerrit

    Related details

    Attention set is empty
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 6
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 16:28:25 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 12:58:19 PMMar 6
    to Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny voted and added 1 comment

    Votes added by Michal Mocny

    Commit-Queue+1

    1 comment

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 292, Patchset 5: SoftNavigationContext* context_for_task =
    Scott Haseley . resolved

    Move above line 287 and use that in the ternary expression?

    Michal Mocny

    sg, originally I didnt even have this but some of the tests failed because I made mistakes while setting them up so added this guard. It will be possible to remove completely, I just wanted to check the try-bots with it. Should have left a comment.

    I could also leave this in, but add NotFatal? since the worst effect of this getting wrong is that we assign the wrong id/starttime to the wrong context. We should know, but maybe not worth crashing.

    Michal Mocny

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 7
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 17:58:14 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Johannes Henkel (Gerrit)

    unread,
    Mar 6, 2026, 2:43:11 PMMar 6
    to Michal Mocny, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Michal Mocny and Scott Haseley

    Johannes Henkel added 1 comment

    Patchset-level comments
    File-level comment, Patchset 7 (Latest):
    Johannes Henkel . resolved

    https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/http/tests/inspector-protocol/tracing/soft-navigations-expected.txt;l=38

    Looks that this line (processingEnd) needs to be deleted, to reflect that it's no longer part of the SoftNavigation object.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Michal Mocny
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 7
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 19:43:02 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Mar 6, 2026, 3:18:52 PMMar 6
    to Michal Mocny, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Michal Mocny

    Scott Haseley added 5 comments

    Patchset-level comments
    Scott Haseley . resolved

    Just a couple comments, will review again after lunch.

    File third_party/blink/renderer/core/timing/soft_navigation_context.h
    Line 74, Patchset 5: // Soft LCP. It is the startTime of the last event timing entry before first
    // paint.
    Michal Mocny . resolved

    this changed. It is now first event timing.

    Pray I do not change it further :)

    Michal Mocny

    Done

    Scott Haseley

    😄

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 167, Patchset 5 (Parent): if (!event.IsFullyTrusted()) {
    return std::nullopt;
    }
    Scott Haseley . unresolved

    Do we lose this check? I think this is problematic since that was added to fix a crash / unexpected behavior for creating contexts during simulated events.

    Michal Mocny

    I can add the check back, but my expectation was that this check was part of the mini-interaction-event-scope machinery that SNH tried to minic and is being wholesale replaced.

    I didn't think that ICP should apply to a subset of Interactions only, and that all the semantics should be up in Event Timing.

    So, if this indeed still fails, I think it would be better to move up to the Event Timing scope and prevent such events from being Interactions.

    ---

    You mention this applies to simulated events-- if you mean web automation tools, then maybe we need to keep allowing Event TIming to measure those, but should just turn off the context and leave here.

    If you mean real user simulated events, if there is some gap where event timing isn't filtering enough, then we certainly should move up there.

    WDYT?

    Scott Haseley

    The problem was simulated event (untrusted) causing a trusted event. This happens because of form controls. See https://chromium-review.googlesource.com/c/chromium/src/+/7466724 (if you're passing that test, this might be okay now)

    Scott Haseley

    Ah, yeah it's still failing.

    The problem is that if you dispatch a simulated click to an element with a target, we dispatch a trusted click to the target. So we create EventTimings for such events, but soft navs filters them out.

    I suspect these should be filtered out from EventTiming as well, and maybe that's relatively safe to do? Not sure.

    The test case: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/wpt_internal/task-tracking/soft-navigation-heuristics/non-fully-trusted-click.html

    Line 227, Patchset 5: // is tracking it. If the context comes from a task that crossed from
    // another, we might have a different SNH instance. This seems to fail
    Scott Haseley . resolved

    nit: removing "created in one window" makes sound unclear to me now.

    Michal Mocny

    sg.

    I wonder if EnsureContextForCurrentWindow should just be folded into GetSoftNavigationContextForCurrentTask() now that we don't pass context* around?

    The only other call site is `ReportSoftNavigationToMetrics` but that is already after we emit to perf timeline and have a whole bunch of effects, so probably not needed there.

    (Ill leave for this patch)

    Michal Mocny

    After the change to the "hot path" check for SNH, this function became a one liner-- so I just inlined it and remvoed it.

    Scott Haseley

    Sweet!

    Line 248, Patchset 7 (Latest): // TODO(crbug.com/40871933): We don't care to support datetime modals, but
    // this behaviour might be similar for iframes, and might be worth
    // supporting.
    Scott Haseley . unresolved

    note: We ran into this in practice with window.open(), in which case you get two main frames in the same process that can script each other.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Michal Mocny
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 7
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 20:18:42 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 3:23:16 PMMar 6
    to Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Scott Haseley

    Michal Mocny added 6 comments

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 269, Patchset 6 (Parent): // `heuristics` will be null if the `window_` was detached but this context
    Michal Mocny . resolved

    restore this

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 167, Patchset 5 (Parent): if (!event.IsFullyTrusted()) {
    return std::nullopt;
    }
    Scott Haseley . resolved

    Do we lose this check? I think this is problematic since that was added to fix a crash / unexpected behavior for creating contexts during simulated events.

    Michal Mocny

    I can add the check back, but my expectation was that this check was part of the mini-interaction-event-scope machinery that SNH tried to minic and is being wholesale replaced.

    I didn't think that ICP should apply to a subset of Interactions only, and that all the semantics should be up in Event Timing.

    So, if this indeed still fails, I think it would be better to move up to the Event Timing scope and prevent such events from being Interactions.

    ---

    You mention this applies to simulated events-- if you mean web automation tools, then maybe we need to keep allowing Event TIming to measure those, but should just turn off the context and leave here.

    If you mean real user simulated events, if there is some gap where event timing isn't filtering enough, then we certainly should move up there.

    WDYT?

    Scott Haseley

    The problem was simulated event (untrusted) causing a trusted event. This happens because of form controls. See https://chromium-review.googlesource.com/c/chromium/src/+/7466724 (if you're passing that test, this might be okay now)

    Michal Mocny

    Done

    Line 234, Patchset 5: for (const auto& tracked_context : interaction_id_to_context_.Values()) {
    Scott Haseley . resolved

    I think we need to treat this as a hot path (dom mods where we have a context), and I'm worried about iterating here. Maybe it's time to put a back-link on context to the heuristics its associated with?

    Michal Mocny

    Let me see if understand what you mean:

    • A task can become scheduled on a window
    • That task might have state which has a context*
    • That task might modify dom (etc) and call into SNH static members
    • Now we need to check, which can be expensive, if this SNH map for *this* window was *the* window for this context

    But if we just stored the back pointer from SNC to SNC we could just check directly on the one context.

    SGTM.

    Michal Mocny

    I added this, because I think its useful to have a backpointer... but I noticed that SNC already has a window_ and I think we can get SNH from window_, and the goal is to check for this window is the original window... I think

    Scott Haseley

    Thought of that at 4AM in my sleep too... Yeah I think we can just check context->GetWindow() == Window() (making these up). That was why this was added IIRC (cross-window main frame case w/ window.opener()).

    If we want to (eventually) exclude other contexts (e.g. if we shutdown early), we can check if they've been shutdown or whatever.

    Michal Mocny

    Done

    Line 248, Patchset 7 (Latest): // TODO(crbug.com/40871933): We don't care to support datetime modals, but
    // this behaviour might be similar for iframes, and might be worth
    // supporting.
    Scott Haseley . resolved

    note: We ran into this in practice with window.open(), in which case you get two main frames in the same process that can script each other.

    Michal Mocny

    (this comment just moved from somewhere earlier, I didn't add it-- I hope nothing abut the specifics change here.)

    Line 578, Patchset 6: SoftNavigationContext* context = GetRelevantContext(interaction_id);
    Michal Mocny

    Great points-- but I think this would be WAI and the fact that each attempt to get a context by id with an event timing doesn't assume there was a past event means this should just work.

    Or do you spot a problem?

    We should add tests for it afterwards!

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.cc
    Line 35, Patchset 5: /*navigation_id=*/1, PerformanceTimelineEntryIdInfo(1, 1));
    Michal Mocny . resolved

    (From AI reviewer:)

    Hardcoding the interaction ID to (1, 1) can lead to incorrect test behavior. For example, in `SoftNavigationHeuristicsTest.HeuristicNotResetDuringGCWithActiveContext`, two separate click events are simulated, but they will end up with the same interaction ID and reuse the same `SoftNavigationContext`, which is likely not the intent.

    Consider using an ID generator here, or passing the ID in as a parameter, similar to the fix in `InteractionEffectsMonitorTest`.

    Michal Mocny

    Cannot use a generator here, but we will move this into a test base that will do this, in a subsequent patch. The tests that need separate ids can manually set them, for now.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 7
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 20:23:10 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 6, 2026, 3:51:47 PMMar 6
    to Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Scott Haseley

    Michal Mocny voted and added 1 comment

    Votes added by Michal Mocny

    Commit-Queue+1

    1 comment

    Patchset-level comments
    Johannes Henkel . resolved

    https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/web_tests/http/tests/inspector-protocol/tracing/soft-navigations-expected.txt;l=38

    Looks that this line (processingEnd) needs to be deleted, to reflect that it's no longer part of the SoftNavigation object.

    Michal Mocny

    I added it back to tracing for now, I thought it wasn't needed at all but forgot about these tests.

    We could also expose more of the event timings if we want... or even the full list of them.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Johannes Henkel
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 9
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Fri, 06 Mar 2026 20:51:39 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Johannes Henkel <joha...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Mar 6, 2026, 7:59:09 PMMar 6
    to Michal Mocny, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Michal Mocny

    Scott Haseley added 13 comments

    File third_party/blink/renderer/core/loader/document_loader.cc
    Line 1628, Patchset 11 (Latest): InteractionContextWrapperScope interaction_context_wrapper;
    Scott Haseley . unresolved

    nit/optional: maybe comment that browser-initiated navigations are considered interactions and this scope sets up handling that for metrics?

    Line 1697, Patchset 11 (Latest): }
    Scott Haseley . unresolved

    ultra-nit: probably keep the newline before this and add one after to separate the task-attribution block

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 34, Patchset 11 (Latest):// is wrapper in this scope, it std::move() the task_scope up to it instead.
    Scott Haseley . unresolved

    ```suggestion
    // is wrapped in this scope, it std::move()d the task_scope up to it instead.
    ```

    Line 31, Patchset 11 (Latest):// This class is used to "hoist" a `TaskAttributionTracker::TaskScope` up to the
    Scott Haseley . unresolved

    Thinking about this a bit more, I think the hoisting is a problem. Having the outer scope is nice, but it would need to initialize the state. The invariant is supposed to be that all TaskScopes are "properly nested", like trace events, and I think this breaks that.

    For example, suppose you have A() calls B() calls C().

     - A() runs, creating an outer InteractionContextWrapperScope scope, initially with the nullopt TaskScope
    - A() calls B(), which sets a task state variable (new TaskScope). That scope will capture the current task state (nothing) and restore that upon completion
    - B() calls C(), which initializes the outer scope's TaskScope. The current task state (B's state) is captured as the "state to restore".
    - C() ends
    - B() ends. The null state is restored --> (outer scope is borked!)
    - A() ends. B's state is restored --> state leak!

    (I actually think I need to nix the TaskScope move c'tors!)

    File third_party/blink/renderer/core/timing/event_timing.cc
    Line 74, Patchset 11 (Latest): if (!event.IsFullyTrusted()) {
    Scott Haseley . unresolved

    Do you know if there's a spec issue for this? This could be a compat issue.

    File third_party/blink/renderer/core/timing/soft_navigation_context.h
    Line 142, Patchset 11 (Latest): void AddEventTiming(PerformanceEventTiming* entry);
    Scott Haseley . unresolved

    Can we remove this? `last_event_timing_` doesn't matter anymore now that you're using the first one.

    Line 47, Patchset 11 (Latest): explicit SoftNavigationContext(LocalDOMWindow& window,
    Scott Haseley . unresolved

    nit: can be removed now

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 37, Patchset 11 (Latest): TRACE_EVENT_BEGIN("loading", "SoftNavigation",
    Scott Haseley . resolved

    nice

    Line 67, Patchset 11 (Latest): CHECK(initial_event_timing_);
    Scott Haseley . unresolved

    nit: You could probably (?) make `initial_event_timing_` const and/or remove this check, since it's already guaranteed to be valid in the c'tor and we don't change it.

    Line 171, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . unresolved
    Did something change that can make this null now, like in tests? Previously, the heuristics was guaranteed to be valid because:
    - It's created by the heuristics class (except in tests)
    - if window_ had a heuristics, it's guaranteed to stay until detach
    - This is shut down on detatch, and OnPaintFinished() shouldn't be called after detach
    Line 307, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . resolved

    You didn't like my style? :P

    (FWIW I did that to be consistent with the `if (!condition) { return }` and have the actual logic at the end, as is somewhat idiomatic in chrome (not always tho..))

    Line 341, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . unresolved

    Similar question, have the guarantees changed? This should never be called after detach.

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Scott Haseley

    The problem with the last one is the non-determinism -- sometimes things are grouped, sometimes they're not, depending on GC.

    I think it's fine for OT_v1 and shouldn't block this, but I think there's a disconnect in the layering that maybe we can fix when InteractionContext moves out of soft navs, like maybe the context creation and mapping needs to be built into the responsiveness metrics state machine (w/ stronger lifetime guarantees).

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Johannes Henkel
    • Michal Mocny
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 11
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Daniel Cheng <dch...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Sat, 07 Mar 2026 00:58:59 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Mar 6, 2026, 11:00:23 PMMar 6
    to Michal Mocny, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Michal Mocny

    Scott Haseley added 1 comment

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 31, Patchset 11 (Latest):// This class is used to "hoist" a `TaskAttributionTracker::TaskScope` up to the
    Scott Haseley . unresolved

    Thinking about this a bit more, I think the hoisting is a problem. Having the outer scope is nice, but it would need to initialize the state. The invariant is supposed to be that all TaskScopes are "properly nested", like trace events, and I think this breaks that.

    For example, suppose you have A() calls B() calls C().

     - A() runs, creating an outer InteractionContextWrapperScope scope, initially with the nullopt TaskScope
    - A() calls B(), which sets a task state variable (new TaskScope). That scope will capture the current task state (nothing) and restore that upon completion
    - B() calls C(), which initializes the outer scope's TaskScope. The current task state (B's state) is captured as the "state to restore".
    - C() ends
    - B() ends. The null state is restored --> (outer scope is borked!)
    - A() ends. B's state is restored --> state leak!

    (I actually think I need to nix the TaskScope move c'tors!)

    Scott Haseley

    Update: I think this is something task attribution should solve, not event timing. Really this is a problem with propagating task state from the intercept() to handler(), which is clear causation. Let me try to add that.

    Gerrit-Comment-Date: Sat, 07 Mar 2026 04:00:08 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Mar 7, 2026, 2:35:09 AMMar 7
    to Michal Mocny, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Michal Mocny

    Scott Haseley added 1 comment

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 31, Patchset 11 (Latest):// This class is used to "hoist" a `TaskAttributionTracker::TaskScope` up to the
    Scott Haseley . unresolved

    Thinking about this a bit more, I think the hoisting is a problem. Having the outer scope is nice, but it would need to initialize the state. The invariant is supposed to be that all TaskScopes are "properly nested", like trace events, and I think this breaks that.

    For example, suppose you have A() calls B() calls C().

     - A() runs, creating an outer InteractionContextWrapperScope scope, initially with the nullopt TaskScope
    - A() calls B(), which sets a task state variable (new TaskScope). That scope will capture the current task state (nothing) and restore that upon completion
    - B() calls C(), which initializes the outer scope's TaskScope. The current task state (B's state) is captured as the "state to restore".
    - C() ends
    - B() ends. The null state is restored --> (outer scope is borked!)
    - A() ends. B's state is restored --> state leak!

    (I actually think I need to nix the TaskScope move c'tors!)

    Scott Haseley

    Update: I think this is something task attribution should solve, not event timing. Really this is a problem with propagating task state from the intercept() to handler(), which is clear causation. Let me try to add that.

    Scott Haseley

    Something like https://chromium-review.googlesource.com/c/chromium/src/+/7645691. That makes the last wpt_internal test pass w/ the previous version of this patch.

    It turned out to be annoying because there can be a TaskScope higher up because of pushState, so we need different behavior than what we do for events (i.e. we have to overwrite even if JS is running). This could be an interesting thing to discuss for AsyncContext.

    Gerrit-Comment-Date: Sat, 07 Mar 2026 07:34:59 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 7, 2026, 8:02:52 AMMar 7
    to Daniel Cheng, Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Scott Haseley

    Michal Mocny added 4 comments

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 31, Patchset 11 (Latest):// This class is used to "hoist" a `TaskAttributionTracker::TaskScope` up to the
    Scott Haseley . unresolved

    Thinking about this a bit more, I think the hoisting is a problem. Having the outer scope is nice, but it would need to initialize the state. The invariant is supposed to be that all TaskScopes are "properly nested", like trace events, and I think this breaks that.

    For example, suppose you have A() calls B() calls C().

     - A() runs, creating an outer InteractionContextWrapperScope scope, initially with the nullopt TaskScope
    - A() calls B(), which sets a task state variable (new TaskScope). That scope will capture the current task state (nothing) and restore that upon completion
    - B() calls C(), which initializes the outer scope's TaskScope. The current task state (B's state) is captured as the "state to restore".
    - C() ends
    - B() ends. The null state is restored --> (outer scope is borked!)
    - A() ends. B's state is restored --> state leak!

    (I actually think I need to nix the TaskScope move c'tors!)

    Scott Haseley

    Update: I think this is something task attribution should solve, not event timing. Really this is a problem with propagating task state from the intercept() to handler(), which is clear causation. Let me try to add that.

    Scott Haseley

    Something like https://chromium-review.googlesource.com/c/chromium/src/+/7645691. That makes the last wpt_internal test pass w/ the previous version of this patch.

    It turned out to be annoying because there can be a TaskScope higher up because of pushState, so we need different behavior than what we do for events (i.e. we have to overwrite even if JS is running). This could be an interesting thing to discuss for AsyncContext.

    Michal Mocny

    Sweet! taking a look.

    And yeah this makes me feel a lot better about :D

    File third_party/blink/renderer/core/timing/event_timing.cc
    Line 74, Patchset 11 (Latest): if (!event.IsFullyTrusted()) {
    Scott Haseley . resolved

    Do you know if there's a spec issue for this? This could be a compat issue.

    Michal Mocny

    I havent filed one, yet. A first pass suggests there is no isFullyTrusted spec concept, so we could either explain the use case, or just explain in terms of "userInitiated" as part of adding navigate.

    Also, this comes to mind: https://github.com/w3c/largest-contentful-paint/issues/105

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 67, Patchset 11 (Latest): CHECK(initial_event_timing_);
    Scott Haseley . unresolved

    nit: You could probably (?) make `initial_event_timing_` const and/or remove this check, since it's already guaranteed to be valid in the c'tor and we don't change it.

    Michal Mocny

    This check actually failed on the tryjobs on this test yesterday: https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc;l=18?q=MetricIntegrationTest.FirstInputDelay

    It looks like the test simulated input then unloads the page.

    I wonder if we are reporting SNC (to tracing / metric?) during teardown and no longer have the event timing entry?

    File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
    Line 578, Patchset 6: SoftNavigationContext* context = GetRelevantContext(interaction_id);
    Scott Haseley . resolved
    Michal Mocny

    So, either we have:

    • Context_v1_for_interaction1 for all events, or
    • Context_v1_fro_interaction1, then Context_v2_fro_interaction1

    Two distinct context, but for the same interaction id, and ultimately matching the same paints (because v1 will only gc if it has no effects).

    The only difference is that today we will report the startTime for the first event vs second event-- but this is already something I want to change by default: the "last event before first effect" should roughly match intuitions, but for practical reasons might need to be "last task/animation frame before first effect, and the first event within that task/animation frame".

    Filed: crbug.com/490552221

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Johannes Henkel
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
    Gerrit-Change-Number: 7638455
    Gerrit-PatchSet: 11
    Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-CC: Daniel Cheng <dch...@chromium.org>
    Gerrit-CC: Johannes Henkel <joha...@chromium.org>
    Gerrit-CC: Nate Chapin <jap...@chromium.org>
    Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Sat, 07 Mar 2026 13:02:46 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Scott Haseley <shas...@chromium.org>
    Comment-In-Reply-To: Michal Mocny <mmo...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 7, 2026, 8:03:09 AMMar 7
    to Daniel Cheng, Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Scott Haseley

    Michal Mocny added 1 comment

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 31, Patchset 11 (Latest):// This class is used to "hoist" a `TaskAttributionTracker::TaskScope` up to the
    Scott Haseley . resolved

    Thinking about this a bit more, I think the hoisting is a problem. Having the outer scope is nice, but it would need to initialize the state. The invariant is supposed to be that all TaskScopes are "properly nested", like trace events, and I think this breaks that.

    For example, suppose you have A() calls B() calls C().

     - A() runs, creating an outer InteractionContextWrapperScope scope, initially with the nullopt TaskScope
    - A() calls B(), which sets a task state variable (new TaskScope). That scope will capture the current task state (nothing) and restore that upon completion
    - B() calls C(), which initializes the outer scope's TaskScope. The current task state (B's state) is captured as the "state to restore".
    - C() ends
    - B() ends. The null state is restored --> (outer scope is borked!)
    - A() ends. B's state is restored --> state leak!

    (I actually think I need to nix the TaskScope move c'tors!)

    Scott Haseley

    Update: I think this is something task attribution should solve, not event timing. Really this is a problem with propagating task state from the intercept() to handler(), which is clear causation. Let me try to add that.

    Scott Haseley

    Something like https://chromium-review.googlesource.com/c/chromium/src/+/7645691. That makes the last wpt_internal test pass w/ the previous version of this patch.

    It turned out to be annoying because there can be a TaskScope higher up because of pushState, so we need different behavior than what we do for events (i.e. we have to overwrite even if JS is running). This could be an interesting thing to discuss for AsyncContext.

    Michal Mocny

    Sweet! taking a look.

    And yeah this makes me feel a lot better about :D

    Michal Mocny

    Acknowledged

    Gerrit-Comment-Date: Sat, 07 Mar 2026 13:03:03 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Michal Mocny (Gerrit)

    unread,
    Mar 7, 2026, 8:44:22 AMMar 7
    to Daniel Cheng, Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
    Attention needed from Johannes Henkel and Scott Haseley

    Michal Mocny added 10 comments

    File third_party/blink/renderer/core/events/pop_state_event.h
    Line 90, Patchset 5: const PerformanceTimelineEntryIdInfo interaction_id_ =
    Scott Haseley . resolved

    I know it's rather innocuous having this, but I think it would be better to push this to the patch it's used in, unless you can do a stack and you think we'll get them both in before branch. Same for HashChangeEvent.

    Michal Mocny

    Sg. This was more of an "initial direction" that proved unneeded.

    Michal Mocny

    Done

    File third_party/blink/renderer/core/loader/document_loader.cc
    Line 1628, Patchset 11 (Latest): InteractionContextWrapperScope interaction_context_wrapper;
    Scott Haseley . resolved

    nit/optional: maybe comment that browser-initiated navigations are considered interactions and this scope sets up handling that for metrics?

    Michal Mocny

    Done

    Scott Haseley . resolved

    ultra-nit: probably keep the newline before this and add one after to separate the task-attribution block

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/event_timing.h
    Line 34, Patchset 11 (Latest):// is wrapper in this scope, it std::move() the task_scope up to it instead.
    Scott Haseley . resolved

    ```suggestion
    // is wrapped in this scope, it std::move()d the task_scope up to it instead.
    ```

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_context.h
    Line 142, Patchset 11 (Latest): void AddEventTiming(PerformanceEventTiming* entry);
    Scott Haseley . resolved

    Can we remove this? `last_event_timing_` doesn't matter anymore now that you're using the first one.

    Michal Mocny

    Done

    Line 47, Patchset 11 (Latest): explicit SoftNavigationContext(LocalDOMWindow& window,
    Scott Haseley . resolved

    nit: can be removed now

    Michal Mocny

    Done

    File third_party/blink/renderer/core/timing/soft_navigation_context.cc
    Line 67, Patchset 11 (Latest): CHECK(initial_event_timing_);
    Scott Haseley . resolved

    nit: You could probably (?) make `initial_event_timing_` const and/or remove this check, since it's already guaranteed to be valid in the c'tor and we don't change it.

    Michal Mocny

    This check actually failed on the tryjobs on this test yesterday: https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc;l=18?q=MetricIntegrationTest.FirstInputDelay

    It looks like the test simulated input then unloads the page.

    I wonder if we are reporting SNC (to tracing / metric?) during teardown and no longer have the event timing entry?

    Michal Mocny

    Done

    Line 171, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . resolved
    Did something change that can make this null now, like in tests? Previously, the heuristics was guaranteed to be valid because:
    - It's created by the heuristics class (except in tests)
    - if window_ had a heuristics, it's guaranteed to stay until detach
    - This is shut down on detatch, and OnPaintFinished() shouldn't be called after detach
    Michal Mocny

    ty!

    Since I added a helper to this class to GetSoftNavigationHeuristics() I just changed all the call sites to use that. If we need to enforce checks we can do it in one place now (but I dont)

    Line 307, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . resolved

    You didn't like my style? :P

    (FWIW I did that to be consistent with the `if (!condition) { return }` and have the actual logic at the end, as is somewhat idiomatic in chrome (not always tho..))

    Michal Mocny

    I was trying to make all the call sites consistent, but I have now reverted to the previous style because (a) I agree I like this style more, (b) the other call sites are now unconditional, based on your other comments.

    Line 341, Patchset 11 (Latest): if (auto* heuristics = window_->GetSoftNavigationHeuristics()) {
    Scott Haseley . resolved

    Similar question, have the guarantees changed? This should never be called after detach.

    Michal Mocny

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Johannes Henkel
    • Scott Haseley
    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: I32c2c09584340e17b9b7707650041eda6a6a6964
      Gerrit-Change-Number: 7638455
      Gerrit-PatchSet: 11
      Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
      Gerrit-CC: Daniel Cheng <dch...@chromium.org>
      Gerrit-CC: Johannes Henkel <joha...@chromium.org>
      Gerrit-CC: Nate Chapin <jap...@chromium.org>
      Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
      Gerrit-Attention: Scott Haseley <shas...@chromium.org>
      Gerrit-Comment-Date: Sat, 07 Mar 2026 13:44:15 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Michal Mocny (Gerrit)

      unread,
      Mar 7, 2026, 9:08:34 AMMar 7
      to Daniel Cheng, Johannes Henkel, Scott Haseley, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
      Attention needed from Johannes Henkel and Scott Haseley

      Michal Mocny added 1 comment

      File third_party/blink/renderer/core/timing/soft_navigation_context.h
      Line 142, Patchset 11: void AddEventTiming(PerformanceEventTiming* entry);
      Scott Haseley . resolved

      Can we remove this? `last_event_timing_` doesn't matter anymore now that you're using the first one.

      Michal Mocny

      Done

      Michal Mocny

      The issue with the test failure was that we still used the context for tracing/reporting even after calling shutdown(), and I could fix it by swapping the order of calls.

      By changing this to const, I no longer can reset it to nullptr during shutdown. Not sure if that means we rather have it non-const after all.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Johannes Henkel
      • Scott Haseley
      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: I32c2c09584340e17b9b7707650041eda6a6a6964
      Gerrit-Change-Number: 7638455
      Gerrit-PatchSet: 12
      Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
      Gerrit-CC: Daniel Cheng <dch...@chromium.org>
      Gerrit-CC: Johannes Henkel <joha...@chromium.org>
      Gerrit-CC: Nate Chapin <jap...@chromium.org>
      Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
      Gerrit-Attention: Scott Haseley <shas...@chromium.org>
      Gerrit-Comment-Date: Sat, 07 Mar 2026 14:08:27 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Scott Haseley (Gerrit)

      unread,
      Mar 7, 2026, 6:25:32 PMMar 7
      to Michal Mocny, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
      Attention needed from Johannes Henkel and Michal Mocny

      Scott Haseley voted and added 7 comments

      Votes added by Scott Haseley

      Code-Review+1

      7 comments

      Patchset-level comments
      File-level comment, Patchset 13 (Latest):
      Scott Haseley . resolved

      LGTM other than the start time thing

      File third_party/blink/renderer/core/timing/event_timing.cc
      Line 74, Patchset 13 (Latest): if (!event.IsFullyTrusted()) {
      Scott Haseley . unresolved

      Maybe put a blurb in the CL description that this is changing? It's low risk, I think, but good to document the change that way, perhaps.

      File third_party/blink/renderer/core/timing/soft_navigation_context.cc
      Line 56, Patchset 13 (Latest): return initial_event_timing_->GetStartTime();
      Scott Haseley . unresolved

      Might be worth CHECKing that initial_event_timing_->GetStartTime() isn't 0?

      The bot error is showing:
      ```
      Check failed: !new_metrics.start_time.is_zero().
      ```

      Line 67, Patchset 11: CHECK(initial_event_timing_);
      Scott Haseley . unresolved

      nit: You could probably (?) make `initial_event_timing_` const and/or remove this check, since it's already guaranteed to be valid in the c'tor and we don't change it.

      Michal Mocny

      This check actually failed on the tryjobs on this test yesterday: https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc;l=18?q=MetricIntegrationTest.FirstInputDelay

      It looks like the test simulated input then unloads the page.

      I wonder if we are reporting SNC (to tracing / metric?) during teardown and no longer have the event timing entry?

      Michal Mocny

      Done

      Scott Haseley

      Oh totally missed that it was cleared in Shutdown(), and const didn't initially make sense. Could be good to be consistent and clear that too, but either way is fine.

      File third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
      Line 120, Patchset 13 (Latest): SoftNavigationContext* GetRelevantContext(
      Scott Haseley . unresolved

      Can you add comments for this one? The other two are straightforward, but I don't know what this one does.

      Maybe also something like `GetContextForNavigation()` since that's what it's used for?

      Line 115, Patchset 13 (Latest): SoftNavigationContext* GetSoftNavigationContextForInteractionId(
      Scott Haseley . unresolved

      I think all 3 of these methods can/should be private.

      File third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
      Line 289, Patchset 13 (Latest): if (new_url == old_url) {
      Scott Haseley . resolved

      Nice, I like consolidating all of the decisions here.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Johannes Henkel
      • Michal Mocny
      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: I32c2c09584340e17b9b7707650041eda6a6a6964
      Gerrit-Change-Number: 7638455
      Gerrit-PatchSet: 13
      Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
      Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
      Gerrit-CC: Daniel Cheng <dch...@chromium.org>
      Gerrit-CC: Johannes Henkel <joha...@chromium.org>
      Gerrit-CC: Nate Chapin <jap...@chromium.org>
      Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
      Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
      Gerrit-Comment-Date: Sat, 07 Mar 2026 23:25:21 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Michal Mocny (Gerrit)

      unread,
      Mar 8, 2026, 8:48:14 AMMar 8
      to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
      Attention needed from Johannes Henkel

      Michal Mocny added 5 comments

      File third_party/blink/renderer/core/timing/event_timing.cc
      Line 74, Patchset 13: if (!event.IsFullyTrusted()) {
      Scott Haseley . resolved

      Maybe put a blurb in the CL description that this is changing? It's low risk, I think, but good to document the change that way, perhaps.

      Michal Mocny

      Done

      File third_party/blink/renderer/core/timing/soft_navigation_context.cc
      Line 56, Patchset 13: return initial_event_timing_->GetStartTime();
      Scott Haseley . resolved

      Might be worth CHECKing that initial_event_timing_->GetStartTime() isn't 0?

      The bot error is showing:
      ```
      Check failed: !new_metrics.start_time.is_zero().
      ```

      Michal Mocny

      Added here and constructor, in case theres some issue with it changing between init and reporting/tracing (since we did have an issue with reporting right after destroy, earlier)

      Line 67, Patchset 11: CHECK(initial_event_timing_);
      Scott Haseley . resolved

      nit: You could probably (?) make `initial_event_timing_` const and/or remove this check, since it's already guaranteed to be valid in the c'tor and we don't change it.

      Michal Mocny

      This check actually failed on the tryjobs on this test yesterday: https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc;l=18?q=MetricIntegrationTest.FirstInputDelay

      It looks like the test simulated input then unloads the page.

      I wonder if we are reporting SNC (to tracing / metric?) during teardown and no longer have the event timing entry?

      Michal Mocny

      Done

      Scott Haseley

      Oh totally missed that it was cleared in Shutdown(), and const didn't initially make sense. Could be good to be consistent and clear that too, but either way is fine.

      Michal Mocny

      Done

      File third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
      Line 120, Patchset 13: SoftNavigationContext* GetRelevantContext(
      Scott Haseley . resolved

      Can you add comments for this one? The other two are straightforward, but I don't know what this one does.

      Maybe also something like `GetContextForNavigation()` since that's what it's used for?

      Michal Mocny

      Done

      Line 115, Patchset 13: SoftNavigationContext* GetSoftNavigationContextForInteractionId(
      Scott Haseley . resolved

      I think all 3 of these methods can/should be private.

      Michal Mocny

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Johannes Henkel
      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: I32c2c09584340e17b9b7707650041eda6a6a6964
        Gerrit-Change-Number: 7638455
        Gerrit-PatchSet: 14
        Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
        Gerrit-CC: Daniel Cheng <dch...@chromium.org>
        Gerrit-CC: Johannes Henkel <joha...@chromium.org>
        Gerrit-CC: Nate Chapin <jap...@chromium.org>
        Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
        Gerrit-Comment-Date: Sun, 08 Mar 2026 12:48:08 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: No
        satisfied_requirement
        open
        diffy

        Michal Mocny (Gerrit)

        unread,
        Mar 8, 2026, 9:09:29 AMMar 8
        to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
        Attention needed from Johannes Henkel

        Michal Mocny voted Commit-Queue+2

        Commit-Queue+2
        Open in Gerrit

        Related details

        Attention is currently required from:
        • Johannes Henkel
        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: I32c2c09584340e17b9b7707650041eda6a6a6964
        Gerrit-Change-Number: 7638455
        Gerrit-PatchSet: 16
        Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
        Gerrit-CC: Daniel Cheng <dch...@chromium.org>
        Gerrit-CC: Johannes Henkel <joha...@chromium.org>
        Gerrit-CC: Nate Chapin <jap...@chromium.org>
        Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
        Gerrit-Comment-Date: Sun, 08 Mar 2026 13:09:22 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes
        satisfied_requirement
        open
        diffy

        Michal Mocny (Gerrit)

        unread,
        Mar 8, 2026, 10:10:04 AMMar 8
        to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
        Attention needed from Johannes Henkel

        Michal Mocny voted Commit-Queue+2

        Commit-Queue+2
        Open in Gerrit

        Related details

        Attention is currently required from:
        • Johannes Henkel
        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: I32c2c09584340e17b9b7707650041eda6a6a6964
        Gerrit-Change-Number: 7638455
        Gerrit-PatchSet: 17
        Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
        Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
        Gerrit-CC: Daniel Cheng <dch...@chromium.org>
        Gerrit-CC: Johannes Henkel <joha...@chromium.org>
        Gerrit-CC: Nate Chapin <jap...@chromium.org>
        Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
        Gerrit-Comment-Date: Sun, 08 Mar 2026 14:09:56 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes
        satisfied_requirement
        open
        diffy

        Scott Haseley (Gerrit)

        unread,
        Mar 8, 2026, 1:20:46 PMMar 8
        to Michal Mocny, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
        Attention needed from Johannes Henkel and Michal Mocny

        Scott Haseley voted and added 1 comment

        Votes added by Scott Haseley

        Code-Review+1

        1 comment

        File third_party/blink/renderer/core/timing/soft_navigation_context.cc
        Line 137, Patchset 17 (Latest): if (HasDomModification() && HasUrl()) {
        Scott Haseley . unresolved

        I wonder if this check (processing end not being null) was making the unit tests pass before. Could you add TimeOrigin() condition to this to get around the failure?

        Also, not totally sure, but without MockTime in unit tests, maybe processing end can also be null?

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Johannes Henkel
        • Michal Mocny
        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: I32c2c09584340e17b9b7707650041eda6a6a6964
          Gerrit-Change-Number: 7638455
          Gerrit-PatchSet: 17
          Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
          Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
          Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
          Gerrit-CC: Daniel Cheng <dch...@chromium.org>
          Gerrit-CC: Johannes Henkel <joha...@chromium.org>
          Gerrit-CC: Nate Chapin <jap...@chromium.org>
          Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
          Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
          Gerrit-Comment-Date: Sun, 08 Mar 2026 17:20:33 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Michal Mocny (Gerrit)

          unread,
          Mar 8, 2026, 3:07:12 PMMar 8
          to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
          Attention needed from Johannes Henkel

          Michal Mocny added 1 comment

          File third_party/blink/renderer/core/timing/soft_navigation_context.cc
          Line 137, Patchset 17 (Latest): if (HasDomModification() && HasUrl()) {
          Scott Haseley . resolved

          I wonder if this check (processing end not being null) was making the unit tests pass before. Could you add TimeOrigin() condition to this to get around the failure?

          Also, not totally sure, but without MockTime in unit tests, maybe processing end can also be null?

          Michal Mocny

          Good idea. I can remove the previous fallback to processing_start in that case, and just check if this is null and leave it un-emitted if so.

          Not ideal, but sufficient, for now.

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Johannes Henkel
          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: I32c2c09584340e17b9b7707650041eda6a6a6964
            Gerrit-Change-Number: 7638455
            Gerrit-PatchSet: 17
            Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
            Gerrit-CC: Daniel Cheng <dch...@chromium.org>
            Gerrit-CC: Johannes Henkel <joha...@chromium.org>
            Gerrit-CC: Nate Chapin <jap...@chromium.org>
            Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
            Gerrit-Comment-Date: Sun, 08 Mar 2026 19:07:03 +0000
            satisfied_requirement
            open
            diffy

            Michal Mocny (Gerrit)

            unread,
            Mar 8, 2026, 3:08:58 PMMar 8
            to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
            Attention needed from Johannes Henkel

            Michal Mocny voted Commit-Queue+2

            Commit-Queue+2
            Open in Gerrit

            Related details

            Attention is currently required from:
            • Johannes Henkel
            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: I32c2c09584340e17b9b7707650041eda6a6a6964
            Gerrit-Change-Number: 7638455
            Gerrit-PatchSet: 18
            Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
            Gerrit-CC: Daniel Cheng <dch...@chromium.org>
            Gerrit-CC: Johannes Henkel <joha...@chromium.org>
            Gerrit-CC: Nate Chapin <jap...@chromium.org>
            Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
            Gerrit-Comment-Date: Sun, 08 Mar 2026 19:08:53 +0000
            Gerrit-HasComments: No
            Gerrit-Has-Labels: Yes
            satisfied_requirement
            open
            diffy

            Michal Mocny (Gerrit)

            unread,
            Mar 8, 2026, 7:21:48 PMMar 8
            to Scott Haseley, Daniel Cheng, Johannes Henkel, Chromium LUCI CQ, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org
            Attention needed from Johannes Henkel

            Michal Mocny voted Commit-Queue+2

            Commit-Queue+2
            Open in Gerrit

            Related details

            Attention is currently required from:
            • Johannes Henkel
            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: I32c2c09584340e17b9b7707650041eda6a6a6964
            Gerrit-Change-Number: 7638455
            Gerrit-PatchSet: 20
            Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
            Gerrit-CC: Daniel Cheng <dch...@chromium.org>
            Gerrit-CC: Johannes Henkel <joha...@chromium.org>
            Gerrit-CC: Nate Chapin <jap...@chromium.org>
            Gerrit-Attention: Johannes Henkel <joha...@chromium.org>
            Gerrit-Comment-Date: Sun, 08 Mar 2026 23:21:41 +0000
            Gerrit-HasComments: No
            Gerrit-Has-Labels: Yes
            satisfied_requirement
            open
            diffy

            Chromium LUCI CQ (Gerrit)

            unread,
            Mar 8, 2026, 8:14:05 PMMar 8
            to Michal Mocny, Scott Haseley, Daniel Cheng, Johannes Henkel, Nate Chapin, AyeAye, android-web...@chromium.org, ashleynewson+w...@chromium.org, jmedle...@chromium.org, speed-metrics...@chromium.org, dtapuska+...@chromium.org, gavinp...@chromium.org, blink-rev...@chromium.org, loading...@chromium.org, blink-re...@chromium.org, blink-...@chromium.org, blink-revi...@chromium.org, blink-revi...@chromium.org, blink-rev...@chromium.org, core-timi...@chromium.org

            Chromium LUCI CQ submitted the change with unreviewed changes

            Unreviewed changes

            17 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/renderer/core/timing/soft_navigation_context.cc
            Insertions: 11, Deletions: 12.

            @@ -53,13 +53,6 @@
            }

            base::TimeTicks SoftNavigationContext::TimeOrigin() const {
            - // TODO(crbug.com/490814752): The StartTime value seems to be missing in
            - // some unittests. It should not be missing from any real events-- but we
            - // provide a fallback to `processing_start` (which must be available).
            - if (initial_event_timing_->GetStartTime().is_null()) {
            - return initial_event_timing_->GetEventTimingReportingInfo()
            - ->processing_start_time;
            - }
            return initial_event_timing_->GetStartTime();
            }

            @@ -134,12 +127,18 @@
            }

            bool SoftNavigationContext::SatisfiesSoftNavNonPaintCriteria() const {
            - if (HasDomModification() && HasUrl()) {
            - CHECK(!UrlChangeTime().is_null()); // Implied by HasUrl()
            - CHECK(!TimeOrigin().is_null());
            - return true;
            + // TODO(crbug.com/490814752): Event StartTime value seems to be missing in
            + // some unittests. It should not be missing from any real events.
            + if (TimeOrigin().is_null()) {
            + return false;
            }
            - return false;
            + // These start false, and become true as we observe effects.
            + if (!HasDomModification() || !HasUrl()) {
            + return false;
            + }
            + CHECK(!UrlChangeTime().is_null());
            + CHECK(!TimeOrigin().is_null());
            + return true;
            }

            bool SoftNavigationContext::SatisfiesSoftNavPaintCriteria(
            ```
            ```
            The name of the file: third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
            Insertions: 7, Deletions: 0.

            @@ -537,6 +537,13 @@
            CHECK_EQ(context->GetSoftNavigationHeuristics(), this);

            if (LocalFrameClient* frame_client = frame->Client()) {
            + // TODO(crbug.com/490814752): Some tests simulate events with an impossibly
            + // small start_time value, which is less than the initial reference time,
            + // which makes the duration appear negative. We cannot report such values
            + // without failing expectations (in tests).
            + if (context->TimeOrigin() <= loader->GetTiming().ReferenceMonotonicTime()) {
            + return;
            + }
            blink::SoftNavigationMetricsForReporting metrics = {
            .soft_navigation_offset = context->SoftNavigationOffset(),
            .start_time = loader->GetTiming().MonotonicTimeToPseudoWallTime(
            ```

            Change information

            Commit message:
            [soft-navs] SoftNavigationContext created in terms of Interactions.

            This patch changes SoftNavigationHeuristics from:
            - doing its own interaction tracking via direct hooks into navigation and event dispatch
            - creating (or reusing) new SoftNavigationContext objects
            - establishing task attribution scopes and assigning the new context as task state variables

            To instead now doing:
            - leveraging the existing Event Timing InteractionId machinery for detecting interactions (i.e. ICP is now 1:1 with INP concept)
            - leveraging the existing Event Timing RAII for task attribution scope lifetimes

            This is a long awaited change towards converting SoftNavigationContext
            into a more generalized InteractionContext. The immediate benefit is
            exposing more interaction types to soft-navigatons, giving
            SoftNavigation and InteractionContentfulPaint PerformanceEntry access to
            event timing interactionId and a common shared startTime.

            This also enabled a significant cleanup of now redundant code.

            Small additional change in this patch:
            - Changes the Event Timing check for `isTrusted` with `isFullyTrusted`
            Bug: 418007230, 440302482, 488419096
            Change-Id: I32c2c09584340e17b9b7707650041eda6a6a6964
            Commit-Queue: Michal Mocny <mmo...@chromium.org>
            Reviewed-by: Scott Haseley <shas...@chromium.org>
            Cr-Commit-Position: refs/heads/main@{#1596111}
            Files:
            • M android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt
            • M third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
            • M third_party/blink/renderer/core/dom/events/event_dispatcher.cc
            • M third_party/blink/renderer/core/frame/history.cc
            • M third_party/blink/renderer/core/frame/local_frame_mojo_handler.cc
            • M third_party/blink/renderer/core/loader/document_loader.cc
            • M third_party/blink/renderer/core/loader/document_loader.h
            • M third_party/blink/renderer/core/navigation_api/navigate_event.cc
            • M third_party/blink/renderer/core/navigation_api/navigation_api.cc
            • M third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
            • M third_party/blink/renderer/core/timing/event_timing.cc
            • M third_party/blink/renderer/core/timing/event_timing.h
            • M third_party/blink/renderer/core/timing/interaction_contentful_paint.cc
            • M third_party/blink/renderer/core/timing/interaction_contentful_paint.h
            • M third_party/blink/renderer/core/timing/interaction_contentful_paint.idl
            • M third_party/blink/renderer/core/timing/interaction_effects_monitor_test.cc
            • M third_party/blink/renderer/core/timing/performance_event_timing.cc
            • M third_party/blink/renderer/core/timing/performance_event_timing.h
            • M third_party/blink/renderer/core/timing/performance_timeline_entry_id_generator.h
            • M third_party/blink/renderer/core/timing/soft_navigation_context.cc
            • M third_party/blink/renderer/core/timing/soft_navigation_context.h
            • M third_party/blink/renderer/core/timing/soft_navigation_entry.cc
            • M third_party/blink/renderer/core/timing/soft_navigation_entry.h
            • M third_party/blink/renderer/core/timing/soft_navigation_entry.idl
            • M third_party/blink/renderer/core/timing/soft_navigation_heuristics.cc
            • M third_party/blink/renderer/core/timing/soft_navigation_heuristics.h
            • M third_party/blink/renderer/core/timing/soft_navigation_heuristics_test.cc
            • M third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.cc
            • M third_party/blink/renderer/core/timing/soft_navigation_heuristics_test_util.h
            • M third_party/blink/renderer/core/timing/soft_navigation_paint_attribution_tracker_test.cc
            • M third_party/blink/renderer/core/timing/window_performance.cc
            • M third_party/blink/renderer/core/timing/window_performance.h
            • M third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
            Change size: XL
            Delta: 33 files changed, 454 insertions(+), 601 deletions(-)
            Branch: refs/heads/main
            Submit Requirements:
            • requirement satisfiedCode-Review: +1 by Scott Haseley
            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: I32c2c09584340e17b9b7707650041eda6a6a6964
            Gerrit-Change-Number: 7638455
            Gerrit-PatchSet: 21
            Gerrit-Owner: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
            Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
            Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
            open
            diffy
            satisfied_requirement
            Reply all
            Reply to author
            Forward
            0 new messages