blob: fe99515eed2ce34c340ce948b624f9a12eb29524 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_CORE_PAGE_LOAD_METRICS_OBSERVER_H_
#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_CORE_PAGE_LOAD_METRICS_OBSERVER_H_
#include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
#include "services/metrics/public/cpp/ukm_source.h"
namespace internal {
// NOTE: Some of these histograms are separated into a separate histogram
// specified by the ".Background" suffix. For these events, we put them into the
// background histogram if the web contents was ever in the background from
// navigation start to the event in question.
extern const char kHistogramFirstLayout[];
extern const char kHistogramFirstInputDelay[];
extern const char kHistogramFirstInputTimestamp[];
extern const char kHistogramLongestInputDelay[];
extern const char kHistogramLongestInputTimestamp[];
extern const char kHistogramFirstPaint[];
extern const char kHistogramFirstImagePaint[];
extern const char kHistogramDomContentLoaded[];
extern const char kHistogramLoad[];
extern const char kHistogramFirstContentfulPaint[];
extern const char kHistogramFirstMeaningfulPaint[];
extern const char kHistogramLargestImagePaint[];
extern const char kHistogramLastImagePaint[];
extern const char kHistogramLargestTextPaint[];
extern const char kHistogramLastTextPaint[];
extern const char kHistogramLargestContentPaint[];
extern const char kHistogramTimeToInteractive[];
extern const char kHistogramParseDuration[];
extern const char kHistogramParseBlockedOnScriptLoad[];
extern const char kHistogramParseBlockedOnScriptExecution[];
extern const char kHistogramParseStartToFirstMeaningfulPaint[];
extern const char kBackgroundHistogramFirstLayout[];
extern const char kBackgroundHistogramFirstImagePaint[];
extern const char kBackgroundHistogramDomContentLoaded[];
extern const char kBackgroundHistogramLoad[];
extern const char kBackgroundHistogramFirstPaint[];
extern const char kHistogramLoadTypeFirstContentfulPaintReload[];
extern const char kHistogramLoadTypeFirstContentfulPaintForwardBack[];
extern const char kHistogramLoadTypeFirstContentfulPaintNewNavigation[];
extern const char kHistogramLoadTypeParseStartReload[];
extern const char kHistogramLoadTypeParseStartForwardBack[];
extern const char kHistogramLoadTypeParseStartNewNavigation[];
extern const char kHistogramFailedProvisionalLoad[];
extern const char kHistogramUserGestureNavigationToForwardBack[];
extern const char kHistogramPageTimingForegroundDuration[];
extern const char kHistogramPageTimingForegroundDurationNoCommit[];
extern const char kHistogramForegroundToFirstMeaningfulPaint[];
extern const char kHistogramFirstMeaningfulPaintStatus[];
extern const char kHistogramTimeToInteractiveStatus[];
extern const char kHistogramFirstNonScrollInputAfterFirstPaint[];
extern const char kHistogramFirstScrollInputAfterFirstPaint[];
extern const char kHistogramPageLoadTotalBytes[];
extern const char kHistogramPageLoadNetworkBytes[];
extern const char kHistogramPageLoadCacheBytes[];
extern const char kHistogramPageLoadNetworkBytesIncludingHeaders[];
extern const char kHistogramLoadTypeTotalBytesForwardBack[];
extern const char kHistogramLoadTypeNetworkBytesForwardBack[];
extern const char kHistogramLoadTypeCacheBytesForwardBack[];
extern const char kHistogramLoadTypeTotalBytesReload[];
extern const char kHistogramLoadTypeNetworkBytesReload[];
extern const char kHistogramLoadTypeCacheBytesReload[];
extern const char kHistogramLoadTypeTotalBytesNewNavigation[];
extern const char kHistogramLoadTypeNetworkBytesNewNavigation[];
extern const char kHistogramLoadTypeCacheBytesNewNavigation[];
extern const char kHistogramTotalCompletedResources[];
extern const char kHistogramNetworkCompletedResources[];
extern const char kHistogramCacheCompletedResources[];
extern const char kHistogramInputToNavigation[];
extern const char kBackgroundHistogramInputToNavigation[];
extern const char kHistogramInputToNavigationLinkClick[];
extern const char kHistogramInputToNavigationOmnibox[];
extern const char kHistogramInputToFirstPaint[];
extern const char kBackgroundHistogramInputToFirstPaint[];
extern const char kHistogramInputToFirstContentfulPaint[];
extern const char kBackgroundHistogramInputToFirstContentfulPaint[];
enum FirstMeaningfulPaintStatus {
FIRST_MEANINGFUL_PAINT_RECORDED,
FIRST_MEANINGFUL_PAINT_BACKGROUNDED,
FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE,
FIRST_MEANINGFUL_PAINT_USER_INTERACTION_BEFORE_FMP,
FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_FIRST_CONTENTFUL_PAINT,
FIRST_MEANINGFUL_PAINT_LAST_ENTRY
};
// Different events can prevent us from recording a successful time to
// interactive value, and sometimes several of these failure events can happen
// simultaneously. In the case of multiple invalidating events, we record the
// failure reason in decreasing order of priority of the following:
//
// 1. Did not reach First Meaningful Paint
// 2. Did not reach quiescence
// 3. Page was not in foreground until TTI was detected.
// 4. There was a non-mouse-move user input before interactive time.
//
// Table of conditions and the TTI Status recorded for each case:
// FMP Reached | Quiesence Reached | Always Foreground | No User Input | Status
// True | True | True | True | 0
// True | True | True | False | 2
// True | True | False | * | 1
// True | False | * | * | 3
// False | * | * | * | 4
enum TimeToInteractiveStatus {
// Time to Interactive recorded successfully.
TIME_TO_INTERACTIVE_RECORDED = 0,
// Main thread and network quiescence reached, but the user backgrounded the
// page at least once before reaching quiescence.
TIME_TO_INTERACTIVE_BACKGROUNDED = 1,
// Main thread and network quiescence reached, but there was a non-mouse-move
// user input that hit the renderer main thread between navigation start and
// interactive time, so the detected interactive time is inaccurate. Note that
// Time to Interactive is not invalidated if the user input is after
// interactive time, but before quiescence windows are detected. User input
// invalidation has less priority than backgrounding - if there was an input
// event before reaching interactive, but the page was backgrounded before
// reaching interactive detection, the status is recorded as backgrounded
// instead of user-interaction-before-interactive.
TIME_TO_INTERACTIVE_USER_INTERACTION_BEFORE_INTERACTIVE = 2,
// User left page before main thread and network quiescence, but after First
// Meaningful Paint.
TIME_TO_INTERACTIVE_DID_NOT_REACH_QUIESCENCE = 3,
// User left page before First Meaningful Paint happened, but after First
// Paint. This status will also be recorded if the first meaningful paint was
// reached on the renderer, but invalidated there due to user input. Input
// invalided First Meaningful Paint values do not reach the browser.
TIME_TO_INTERACTIVE_DID_NOT_REACH_FIRST_MEANINGFUL_PAINT = 4,
TIME_TO_INTERACTIVE_LAST_ENTRY
};
} // namespace internal
// Observer responsible for recording 'core' page load metrics. Core metrics are
// maintained by loading-dev team, typically the metrics under
// PageLoad.(Document|Paint|Parse)Timing.*.
class CorePageLoadMetricsObserver
: public page_load_metrics::PageLoadMetricsObserver {
public:
CorePageLoadMetricsObserver();
~CorePageLoadMetricsObserver() override;
// page_load_metrics::PageLoadMetricsObserver:
ObservePolicy OnRedirect(
content::NavigationHandle* navigation_handle) override;
ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
ukm::SourceId source_id) override;
void OnDomContentLoadedEventStart(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnLoadEventStart(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstLayout(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstPaintInPage(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstImagePaintInPage(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstContentfulPaintInPage(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstMeaningfulPaintInMainFrameDocument(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnPageInteractive(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnFirstInputInPage(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnParseStart(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnParseStop(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnComplete(const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& info) override;
void OnFailedProvisionalLoad(
const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
ObservePolicy FlushMetricsOnAppEnterBackground(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& info) override;
void OnUserInput(
const blink::WebInputEvent& event,
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& extra_info) override;
void OnResourceDataUseObserved(
FrameTreeNodeId frame_tree_node_id,
const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&
resources) override;
private:
void RecordTimingHistograms(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& info);
void RecordByteAndResourceHistograms(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& info);
void RecordForegroundDurationHistograms(
const page_load_metrics::mojom::PageLoadTiming& timing,
const page_load_metrics::PageLoadExtraInfo& info,
base::TimeTicks app_background_time);
ui::PageTransition transition_;
bool was_no_store_main_resource_;
// Number of complete resources loaded by the page.
int num_cache_resources_;
int num_network_resources_;
// The number of body (not header) prefilter bytes consumed by completed
// requests for the page.
int64_t cache_bytes_;
int64_t network_bytes_;
// The number of prefilter bytes consumed by completed and partial network
// requests for the page.
int64_t network_bytes_including_headers_;
// Size of the redirect chain, which excludes the first URL.
int redirect_chain_size_;
// True if we've received a non-scroll input (touch tap or mouse up)
// after first paint has happened.
bool received_non_scroll_input_after_first_paint_ = false;
// True if we've received a scroll input after first paint has happened.
bool received_scroll_input_after_first_paint_ = false;
base::TimeTicks first_paint_;
DISALLOW_COPY_AND_ASSIGN(CorePageLoadMetricsObserver);
};
#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_CORE_PAGE_LOAD_METRICS_OBSERVER_H_