Blink's core rendering code hooks into a “detector” that implements the semantics of the metric. Example: PaintTimingDetector
. (This is more of a convention and not a specific shared interface.)
The detector notifies the LocalFrameClient that the metric's value has changed. For some metrics, this uses the generic DidChangePerformanceTiming
method, but other metrics have dedicated methods on this interface.
The LocalFrameClientImpl
notifies the RenderFrame
that the metric's value has changed.
The RenderFrameImpl
notifies PageLoadMetrics
' MetricsRenderFrameObserver
(through a generic observer interface) that the metric's value has changed.
Sometimes, new data is passed in to MetricsRenderFrameObserver
in the same method that notifies it of the change.
But for metrics that rely on DidChangePerformanceTiming
, MetricsRenderFrameObserver
has to go back to Blink to ask for the actual data, by querying the WebPerformance
object, which in turn queries the detector from step 1.
MetricsRenderFrameObserver
passes the new data into PageLoadMetrics
's [PageTimingMetricsSender
](https://source.chromium.org/chromium/chromium/src/+/main:components/page_load_metrics/renderer/page_timing_metrics_sender.h.
PageTimingMetricsSender
buffers the data for up to 1000 ms, then issues an IPC to the browser which is handled by MetricsWebContentsObserver
.
MetricsWebContentsObserver
passes the data to the PageLoadMetricsUpdateDispatcher
for the currently tracked page load.
For some metrics, like FCP, PageLoadMetricsUpdateDispatcher
“merges” updates from all frames (using PageLoadTimingMerger
) into a single page-wide value, which it then passes up to its owner, the PageLoadTracker
.
But for other metrics, PageLoadMetricsUpdateDispatcher
passes per-frame values up to PageLoadTracker
. This is the case for LCP, which is merged by a PageLoadTracker
-owned object (LargestContentfulPaintHandler
) and not by PageLoadMetricsUpdateDispatcher
.
PageLoadTracker
broadcasts metric values (some page-wide, some frame-specific) to various PageLoadMetricsObserver
implementers. Some metrics pass through the generic OnTimingUpdate
method, while others have dedicated methods on the observer interface.
PageLoadMetricsObserver
implementations like UmaPageLoadMetricsObserver
and UkmPageLoadMetricsObserver
perform the final step of recording to UMA/UKM, calling into generic components like base::Histogram
and UkmRecorder
.