How data is passed from renderer to browser for page load metrics observers

  1. 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.)

  2. 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.

  3. The LocalFrameClientImpl notifies the RenderFrame that the metric's value has changed.

  4. The RenderFrameImpl notifies PageLoadMetrics' MetricsRenderFrameObserver (through a generic observer interface) that the metric's value has changed.

  5. 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.

  6. 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.

  7. PageTimingMetricsSender buffers the data for up to 1000 ms, then issues an IPC to the browser which is handled by MetricsWebContentsObserver.

  8. MetricsWebContentsObserver passes the data to the PageLoadMetricsUpdateDispatcher for the currently tracked page load.

  9. 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.

  10. 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.

  11. PageLoadMetricsObserver implementations like UmaPageLoadMetricsObserver and UkmPageLoadMetricsObserver perform the final step of recording to UMA/UKM, calling into generic components like base::Histogram and UkmRecorder.