tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 0b1b8ae99ebb40fd76e3e94ab3e6d7f3ae9b8d1d
parent c17df0353b5a9fb13589a0eead18b30185348094
Author: Nazım Can Altınova <canaltinova@gmail.com>
Date:   Wed,  8 Oct 2025 15:18:17 +0000

Bug 1991587 - Use consistent timestamp for FCP and LCP entries r=jlink,smaug

FCP and LCP were using different timestamps for the same paint. FCP used
`RefreshDriver()->MostRecentRefresh()` (tick start time) while LCP used
`TimeStamp::Now()` captured in the function, causing LCP to be reported
differently compared to FCP.

Both metrics now capture `TimeStamp::Now()` once and share it. This matches
the Paint Timing spec which says to capture "rendering update end time"
when mark paint timing runs, not reuse the tick start timestamp:
https://w3c.github.io/paint-timing/#mark-paint-timing

Differential Revision: https://phabricator.services.mozilla.com/D267757

Diffstat:
Mlayout/base/nsPresContext.cpp | 2+-
Dtesting/web-platform/meta/largest-contentful-paint/first-paint-equals-lcp-text.html.ini | 5-----
Dtesting/web-platform/meta/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html.ini | 6------
Dtesting/web-platform/tests/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html | 55-------------------------------------------------------
4 files changed, 1 insertion(+), 67 deletions(-)

diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp @@ -2760,7 +2760,7 @@ void nsPresContext::NotifyContentfulPaint() { "We should only notify contentful paint during refresh " "driver ticks"); if (!perf->HadFCPTimingEntry()) { - TimeStamp nowTime = rootPresContext->RefreshDriver()->MostRecentRefresh(); + TimeStamp nowTime = mMarkPaintTimingStart; MOZ_ASSERT(!nowTime.IsNull(), "Most recent refresh timestamp should exist since we are in " "a refresh driver tick"); diff --git a/testing/web-platform/meta/largest-contentful-paint/first-paint-equals-lcp-text.html.ini b/testing/web-platform/meta/largest-contentful-paint/first-paint-equals-lcp-text.html.ini @@ -1,5 +0,0 @@ -[first-paint-equals-lcp-text.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [FCP and LCP are the same when there is a single text element in the page.] - expected: FAIL diff --git a/testing/web-platform/meta/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html.ini b/testing/web-platform/meta/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html.ini @@ -1,6 +0,0 @@ -[fcp-ensure-update-the-rendering-step.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [The first-contentful-paint timestamp should be same as the last RAF] - expected: - if (os == "android") and not debug: [PASS, FAIL] diff --git a/testing/web-platform/tests/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html b/testing/web-platform/tests/paint-timing/fcp-only/fcp-ensure-update-the-rendering-step.html @@ -1,55 +0,0 @@ -<!DOCTYPE html> -<head> - <title> - Ensure the timing is marked during the `update the rendering` step. - </title> -</head> -<style> - #main { - width: 100px; - height: 100px; - left: 0px; - position: relative; - top: 0; - background-image: url(../resources/circles.png); - opacity: 0; - } - - #main.contentful { - opacity: 0.1; - } -</style> -<body> -<script src="../resources/utils.js"></script> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<div id="main"></div> -<script> -setup({"hide_test_state": true}); -async_test(function (t) { - assert_implements(window.PerformancePaintTiming, "Paint Timing isn't supported."); - let fired = false; - const main = document.getElementById('main'); - let animationFrameStamps = []; - requestAnimationFrame(function frame(stamp) { - animationFrameStamps.unshift(stamp); - main.className = "contentful"; - while (performance.now() - stamp <= 5) { - /* Busy-wait */ - } - if(!fired) - requestAnimationFrame(frame); - }); - new PerformanceObserver(t.step_func(list=>{ - for (let entry of list.getEntries()) { - if (entry.name == "first-contentful-paint") { - fired = true; - assert_any(assert_approx_equals, entry.startTime, animationFrameStamps, 1, "One of the past requestAnimationFrame should have the same timestamp as paint entry"); - t.done(); - } - } - })).observe({type: "paint"}); -}, 'The first-contentful-paint timestamp should be same as the last RAF'); -</script> -</body> -</html>