Above, we show example PageLoadMetricsObserver
(PLMO) lifetimes for a WebContents
with three main-frame navigations, shown in blue, green, and yellow, with time starting on the left, and ending on the right.
WebContents
, in blue, is instantiated when its navigation starts, and is destroyed when the next navigation in the WebContents
commits (the yellow load).WebContents
is closed. The commit of the yellow navigation causes the PLMO for the previously committed load, in blue, to be destroyed.PageLoadMetricsObserver
lifetimes within a WebContents
often overlap. In particular, if there is a committed load in a WebContents
, the lifetime of its associated PageLoadMetricsObserver
overlaps with the lifetime of subsequent navigations, for the period from the subsequent load’s navigation start until the next navigation commits. We see this for the blue and yellow loads in the example above.
PageLoadMetricsObserver
callback life cyclePageLoadMetricsObserver
(PLMO) implementation is instantiated when a navigation starts. At this time, the OnStart
callback is invoked.OnRedirect
may be invoked one or more times, for each server-side redirect. Note that content-triggered redirects, such as meta refreshes or a JS-based navigations, are separate distinct page loads, and do not cause OnRedirect
to be invoked.OnCommit
is invokedOnFailedProvisionalLoad
is invoked, and the PLMO is destroyed.OnComplete
callback is invoked just before the PLMO is destroyed (due to e.g. a new page load committing, the associated WebContents
being destroyed, etc).Returning to the example above, callbacks are invoked in the following order:
PageLoadMetricsObserver
s for the blue load are instantiated, and OnStart
is invoked on them.OnCommit
is invoked for the blue load’s PLMOs.OnStart
is invoked for them.OnFailedProvisionalLoad
is invoked for the green load’s PLMOs. PLMOs for the green navigation are then destroyed.OnStart
is invoked on them.OnComplete
is invoked for the blue load’s PLMOs. OnCommit
is then invoked for the yellow load’s PLMOs.OnComplete
is invoked for the yellow load’s PLMOs.Additionally, the following callbacks may be invoked during the lifetime of a PageLoadMetricsObserver
:
OnHidden
and OnShown
are invoked as the associated WebContents
is hidden or shown (e.g. when the user switches tabs).FlushMetricsOnAppEnterBackground
callback is invoked to signal to observers that any metrics buffered in memory should be persisted. Once FlushMetricsOnAppEnterBackground
is invoked, the application may be killed without subsequent notification. Note that FlushMetricsOnAppEnterBackground
may be invoked multiple times for a single page load if Chrome transitions from the foreground to background to foreground to background without being killed. Note that this callback is only invoked if the entire Chrome application is backgrounded. It is not invoked if the user e.g. switches between tabs within Chrome.OnLoadedResource
is invoked as each resource on the page finishes loading.OnFirstContentfulPaint
are invoked as the associated page load timing events occur.OnUserInput
is invoked as user input events are received.OnLoadingBehaviorObserved
is invoked as certain page loading behaviors are observed. See the section on loading behaviors below for additional information.OnEnterBackForwardCache
is invoked if the page will enter the Back/Forward cache. Observers may return STOP_OBSERVING
from this callback if they do not wish to continue logging after a page has entered the BFCache, and this is the default implementation for PageLoadMetricsObserver
(it will also call OnComplete
at this time).OnRestoreFromBackForwardCache
is invoked when the page is restored from the Back/Forward cache. This callback is invoked with a NavigationHandle
which will have a different navigation ID to the original page load‘s. Whether metrics should be logged using this new navigation ID, or the original page load’s ID, depends on the desired interpretation of the metrics.PageLoadMetricsObserver
s?Only provisional loads that meet the following criteria are tracked:
In addition, when a load commits, additional criteria are applied at commit time. Only page loads that meet the earlier provisional criteria, as well as the following criteria at commit time, are tracked after commit:
Note that the provisional criteria is applied again at commit time, as navigation attributes such as the URL may have changed between the time a provisional load is started and the time it commits.
Loads that finish and received HTTP response headers but did not commit do not invoke the OnFailedProvisionalLoad
callback. These are special case navigations, such as downloads and HTTP 204/205 responses, which complete successfully but do not result in a committed load.
If a page load is filtered due to the above criteria, no subsequent callbacks will be invoked for the associated PageLoadMetricsObservers
for that page load.
Because not every load meets the commit-time criteria, some PageLoadMetricsObserver
s will see calls to OnStart
and OnRedirect
but no other callbacks.
We intend to allow teams to add custom PageLoad
UMA metrics that relax these constraints as needed. For instance, we could add support for tracking just NTP loads, or chrome:// URLs. If you are interested in tracking metrics using a different set of constraints, please reach out to speed-metrics-dev@chromium.org.
PageLoadMetricsEmbedder::RegisterObservers
method in page_load_metrics_initialize.cc.See https://chromium-review.googlesource.com/c/chromium/src/+/2294392 for an example end-to-end change that adds a new PageLoadMetricsObserver
.
By default, page loads that spend time in the background during the period between navigation start and an event occurring are not included in core page load metrics. Backgrounded pages are often throttled and thus their metrics can be less useful/actionable for understanding page load performance.
For instance, the PageLoad.PaintTiming.NavigationToFirstContentfulPaint
UMA only includes samples for page loads that were in the foreground for the entire period from navigation to first contentful paint. Page loads that were in the background for any period of time between navigation start and first contentful paint are excluded.
Thus, it is recommended that observers not record samples for metrics that occur when a page load is in the background.
An observer that does not want to track any metrics for events that occur after the page has been backgrounded can implement OnHidden
to return STOP_OBSERVING
, and OnStart to return STOP_OBSERVING
if the started_in_foreground
parameter is false.
Observers that track some background metrics can determine if an event happened completely in the foreground using the WasStartedInForegroundOptionalEventInForeground
method. See existing page load metrics observer implementations for examples.
Observers that wish to track metrics for pages that spend time in the background can log metrics for those cases by checking that WasStartedInForegroundOptionalEventInForeground
returns false, and using a separate histogram with a .Background
suffix. For example, PageLoad.PaintTiming.NavigationToFirstContentfulPaint.Background
includes page loads that were in the background at some point in time between navigation start and first contentful paint. In practice, we have not found .Background
histograms to be very useful, other than to track the percentage of page loads that spend time in the background. Observers are discouraged from logging background histograms unless there is a clear reason to do so.
Most observers add their histograms under the PageLoad.Clients.*
prefix. For example, PageLoad.Clients.DataReductionProxy.PaintTiming.NavigationToFirstContentfulPaint
tracks PageLoad.PaintTiming.NavigationToFirstContentfulPaint
for the subset of page loads loaded through the data reduction proxy. It is recommended that observers add metrics under PageLoad.Clients
, as this allows other UMA users to more easily discover these metrics while browsing metrics with the PageLoad.*
prefix.
If your metrics are not likely to be useful to other UMA users interested in page load metrics, you may wish to use a different naming scheme for your metrics. If you have questions, reach out to speed-metrics-dev@chromium.org.
On the Android platform, once the Chrome application goes into the background, it may be killed without subsequent notification. To avoid data loss, observers that buffer metric information in memory may wish to implement the FlushMetricsOnAppEnterBackground
callback to persist metrics when Chrome goes into the background.
Considerations
OnComplete
callback should consider also implementing the FlushMetricsOnAppEnterBackground
callback.FlushMetricsOnAppEnterBackground
may also receive an OnComplete
callback.FlushMetricsOnAppEnterBackground
may be invoked multiple times for a single page load if Chrome transitions from the foreground to background to foreground to background without being killed.PageLoadMetricsObserver
examplesObservers that wish to avoid tracking metrics for some page loads can do so by returning ObservePolicy::STOP_OBSERVING
from observer callbacks that return an ObservePolicy
. For example, an observer that wishes to only track metrics for page loads that match certain criteria at commit, such as the hostname of the committed URL, can implement the OnCommit
callback. If an observer returns STOP_OBSERVING
, no subsequent callbacks will be invoked on the observer.
SignedExchangePageLoadMetricsObserver is an observer that performs page load filtering in the OnCommit callback, tracking only page loads for signed exchanges.
Considerations
PageLoadMetricsObserver
s that want to track pages with certain attributes known in Blink, for example, whether the page is service worker controlled or whether the page loaded a parser blocking script inserted via document.write
, can do so using loading behaviors in the WebLoadingBehaviorFlag
Blink public enum.
To track pages with a certain loading behavior, a PageLoadMetricsObserver
can implement the OnLoadingBehaviorObserved
callback, or check the metadata.behavior_flags
field of the PageLoadExtraInfo
structure that is passed to various PageLoadMetricsObserver
callbacks.
ServiceWorkerPageLoadMetricsObserver
is an observer that tracks metrics for page loads that are controlled by a service worker, as indicated by the WebLoadingBehaviorServiceWorkerControlled
loading behavior flag.
Considerations
WebLoadingBehaviorDocumentWriteBlock
loading behavior may be observed after first contentful paint occurs.OnLoadingBehaviorObserved
callback.OnLoadingBehaviorObserved
. DocumentWritePageLoadMetricsObserver
is an observer that uses this logging strategy.If your observer wants to track a new loading behavior, you can add it to the WebLoadingBehaviorFlag
enum and add instrumentation in Blink to notify the page load metrics infrastructure when the new loading behavior is observed. See the changes to FrameLoader.cpp
in this change for an example change that adds instrumentation to track a new loading behavior.
Observers can track aborted page loads. A page load abort occurs when some event occurs that causes the page load to be terminated. Note that page load abort tracking is somewhat experimental and is subject to change.
Aborts can occur before or after commit. Observers can track aborts that happen before commit by implementing the OnFailedProvisionalLoad callback, and aborts that happen after commit by implementing the OnComplete callback. The current convention is to log aborts that occur before commit using the ‘.BeforeCommit’ histogram suffix, and after commit using a suffix such as ‘.AfterCommit.BeforePaint’.
To determine whether an abort occurred, observers should check whether the abort_type field of the PageLoadExtraInfo structure has a value other than ABORT_NONE. The time until the page load was aborted is available in the time_to_abort field of the PageLoadExtraInfo structure.
AbortsPageLoadMetricsObserver
is an observer that tracks page load abort metrics.
Some observer implementers may wish to track statistics aggregated across multiple page loads. Since a PageLoadMetricsObserver
’s lifetime is bound to a single page load, a separate object with a longer lifetime must be used to track these statistics.
HttpsEngagementPageLoadMetricsObserver
is an observer that tracks statistics aggregated across page loads. The observer forwards information about a page load to the HttpsEngagementService
, which is responsible for aggregating statistics and logging aggregated metrics.