LCP: Use largest painted image for web-exposed entry [chromium/src : main]

0 views
Skip to first unread message

Scott Haseley (Gerrit)

unread,
Dec 17, 2025, 7:19:57 PM12/17/25
to Michal Mocny, Chromium LUCI CQ, chromium...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org, lighthouse-eng-extern...@google.com, speed-metrics...@chromium.org
Attention needed from Michal Mocny

Scott Haseley added 1 comment

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

PTAL (not expecting to land this before the holidays, just want to send it out!). Not sure if we should go "experimental" or just enable this.

Open in Gerrit

Related details

Attention is currently required from:
  • Michal Mocny
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement 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: I5275906769b07aca6c671c846756070333f2b09c
Gerrit-Change-Number: 7269039
Gerrit-PatchSet: 1
Gerrit-Owner: Scott Haseley <shas...@chromium.org>
Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
Gerrit-Comment-Date: Thu, 18 Dec 2025 00:19:48 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Michal Mocny (Gerrit)

unread,
Dec 18, 2025, 2:48:50 PM12/18/25
to Scott Haseley, Chromium LUCI CQ, chromium...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org, lighthouse-eng-extern...@google.com, speed-metrics...@chromium.org
Attention needed from Scott Haseley

Michal Mocny voted and added 4 comments

Votes added by Michal Mocny

Code-Review+1

4 comments

Patchset-level comments
Michal Mocny . resolved

Huzzah!

File third_party/blink/web_tests/external/wpt/largest-contentful-paint/performance-entry-sequence.html
Line 3, Patchset 1 (Latest):<title>Largest Contentful Paint: performance entries are emitted in the expected sequence</title>
Michal Mocny . unresolved

Just FYI that Firefox will not pass this, and landing this into the LCP repo will make it automatically part of the interop work... you can untag it, but I dont know the full process.

(It could also start tentative until we merge in spec changes? Though I can prob get that in alongside this...)

Line 31, Patchset 1 (Latest): container.appendChild(createDivWithText('text1', 'AB'));
Michal Mocny . unresolved

Nit: could you consider adding a third div, which is als smaller, that comes last (after the largest)?

That way, regardless of arbitrary paint order for any implementation (well not guaranteed but higher odds...) you can test that only one (largest) candidate is emitted per paint.

Otherwise you could just be accidentally measuring largest before smaller...

Line 44, Patchset 1 (Latest): // a LargestContentfulPaint entry for image1.
Michal Mocny . unresolved

Is this 100% guaranteed? Is the random appended to ensure no cache?

Open in Gerrit

Related details

Attention is currently required from:
  • Scott Haseley
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: I5275906769b07aca6c671c846756070333f2b09c
    Gerrit-Change-Number: 7269039
    Gerrit-PatchSet: 1
    Gerrit-Owner: Scott Haseley <shas...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-Attention: Scott Haseley <shas...@chromium.org>
    Gerrit-Comment-Date: Thu, 18 Dec 2025 19:48:42 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Jan 7, 2026, 9:20:39 PM (4 days ago) Jan 7
    to Michal Mocny, Chromium LUCI CQ, chromium...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org, lighthouse-eng-extern...@google.com, speed-metrics...@chromium.org
    Attention needed from Michal Mocny

    Scott Haseley added 3 comments

    File third_party/blink/web_tests/external/wpt/largest-contentful-paint/performance-entry-sequence.html
    Line 3, Patchset 1:<title>Largest Contentful Paint: performance entries are emitted in the expected sequence</title>
    Michal Mocny . unresolved

    Just FYI that Firefox will not pass this, and landing this into the LCP repo will make it automatically part of the interop work... you can untag it, but I dont know the full process.

    (It could also start tentative until we merge in spec changes? Though I can prob get that in alongside this...)

    Scott Haseley

    Yeah maybe making it .tentative for now makes sense. I thought there was a predefined list of tests for the interop effort that will trip up edits, but I'm not fully sure how that works.

    Line 31, Patchset 1: container.appendChild(createDivWithText('text1', 'AB'));
    Michal Mocny . unresolved

    Nit: could you consider adding a third div, which is als smaller, that comes last (after the largest)?

    That way, regardless of arbitrary paint order for any implementation (well not guaranteed but higher odds...) you can test that only one (largest) candidate is emitted per paint.

    Otherwise you could just be accidentally measuring largest before smaller...

    Scott Haseley

    Yeah good idea, I'll update this shortly... And yeah this is tricky since paint order _could_ be anything.

    Line 44, Patchset 1: // a LargestContentfulPaint entry for image1.
    Michal Mocny . unresolved

    Is this 100% guaranteed? Is the random appended to ensure no cache?

    Scott Haseley

    It should be. The key here is we don't want the image to load synchronously, otherwise it'll be in this frame. The only time that's _supposed_ to happen is when the image is in the list of "list of available images" [1] (used for de-duping during loading, and I think for reloads), but that's keyed off of absolute URL, so this should prevent reuse there.

    Chrome loads data URIs synchronously, which IIUC is a (maybe willful) spec violation, but this doesn't apply here.

    Preloads and HTTP cache hits are still supposed to have an async hop since it calls out to Fetch, but I haven't tested this in all browsers (I think I have a test showing this is the case in Chrome) -- but regardless, the random query param should prevent a cached/preloaded resource from being used, so I think this is sound.

    [1]https://html.spec.whatwg.org/#list-of-available-images

    ---

    BUT, I'm finding this is flaky locally for another reason: sometimes the feedback for frame N arrives _after_ N+1, so we give everything the timestamp for N+1 :(. So I'm seeing all of the text nodes getting the same timestamp in some cases.

    It looks mostly confined to non-threaded compositing (I've seen weirdness with this mode before wrt presentation callbacks), but it timed out at least once with threaded compositing (although I can't get it to fail now..). Looks like it could be related to the jitter we add or something, as these are delayed tasks.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • 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: I5275906769b07aca6c671c846756070333f2b09c
    Gerrit-Change-Number: 7269039
    Gerrit-PatchSet: 2
    Gerrit-Owner: Scott Haseley <shas...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Thu, 08 Jan 2026 02:20:19 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Michal Mocny <mmo...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Scott Haseley (Gerrit)

    unread,
    Jan 9, 2026, 7:27:51 PM (2 days ago) Jan 9
    to Michal Mocny, Chromium LUCI CQ, chromium...@chromium.org, blink-rev...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, jmedle...@chromium.org, kinuko...@chromium.org, lighthouse-eng-extern...@google.com, speed-metrics...@chromium.org
    Attention needed from Michal Mocny

    Scott Haseley added 1 comment

    File third_party/blink/web_tests/external/wpt/largest-contentful-paint/performance-entry-sequence.html
    Line 44, Patchset 1: // a LargestContentfulPaint entry for image1.
    Michal Mocny . unresolved

    Is this 100% guaranteed? Is the random appended to ensure no cache?

    Scott Haseley

    It should be. The key here is we don't want the image to load synchronously, otherwise it'll be in this frame. The only time that's _supposed_ to happen is when the image is in the list of "list of available images" [1] (used for de-duping during loading, and I think for reloads), but that's keyed off of absolute URL, so this should prevent reuse there.

    Chrome loads data URIs synchronously, which IIUC is a (maybe willful) spec violation, but this doesn't apply here.

    Preloads and HTTP cache hits are still supposed to have an async hop since it calls out to Fetch, but I haven't tested this in all browsers (I think I have a test showing this is the case in Chrome) -- but regardless, the random query param should prevent a cached/preloaded resource from being used, so I think this is sound.

    [1]https://html.spec.whatwg.org/#list-of-available-images

    ---

    BUT, I'm finding this is flaky locally for another reason: sometimes the feedback for frame N arrives _after_ N+1, so we give everything the timestamp for N+1 :(. So I'm seeing all of the text nodes getting the same timestamp in some cases.

    It looks mostly confined to non-threaded compositing (I've seen weirdness with this mode before wrt presentation callbacks), but it timed out at least once with threaded compositing (although I can't get it to fail now..). Looks like it could be related to the jitter we add or something, as these are delayed tasks.

    Scott Haseley
    Re: out-of-order presentation time:
    - When coarsening, we round up to nearest multiple of 4ms and use that as the presentation time. We then post a delayed task with delay = origin + presentation_time - now.
    - But we sometimes get the same presentation timestamp for consecutive frames. This happens a lot more without threaded compositing, but can also happen with threaded compositing, e.g. with dropped frames (which is what I'm seeing)
    - The flakiness results from computing the delay: the target_time (origin + pres_time) is the same, but there's some margin for error since we compute now() and then add that delay back to now() in the scheduling layer

    The new-ish `PostDelayedTaskAt()` should fix this since that would use the target_time directly `SequenceManager` rather than doing more math, and the tie would be broken based on sequence number (posting order). But, it's guarded by a PassKey, so I'll need to get this blessed.

    One alternative is to use a Timer and maintain a list of callbacks, ordered by target_time, and have a single outstanding task (earliest presentation time). But that's basically duplicating the `SequenceManager` logic.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • 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: I5275906769b07aca6c671c846756070333f2b09c
    Gerrit-Change-Number: 7269039
    Gerrit-PatchSet: 2
    Gerrit-Owner: Scott Haseley <shas...@chromium.org>
    Gerrit-Reviewer: Michal Mocny <mmo...@chromium.org>
    Gerrit-Reviewer: Scott Haseley <shas...@chromium.org>
    Gerrit-Attention: Michal Mocny <mmo...@chromium.org>
    Gerrit-Comment-Date: Sat, 10 Jan 2026 00:27:37 +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
    Reply all
    Reply to author
    Forward
    0 new messages