Skip to content

Commit

Permalink
[Merge to M110] Prerender: Add UMAs to debug prerender page load metrics
Browse files Browse the repository at this point in the history
For debugging the issue, this CL adds following UMAs:

- Recording the initiator's visibility (hidden, occluded, visible) on
  prerender activation in PageLoadTracker:
  "PageLoad.Internal.Prerender2.VisibilityAtActivation"
- Recording results of foreground checks in
  PrerenderPageLoadMetricsObserver:
  "PageLoad.Internal.Prerender2.ForegroundCheckResult.{EventType}"

This just adds the metrics and doesn't change functional behavior.

(cherry picked from commit 08dd287)

Bug: 1379491
Change-Id: I11f9932957510238c98ffb758d8fd2b2218e26aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4211892
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1101471}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4248038
Cr-Commit-Position: refs/branch-heads/5481@{#1130}
Cr-Branched-From: 130f3e4-refs/heads/main@{#1084008}
  • Loading branch information
nhiroki authored and Chromium LUCI CQ committed Feb 14, 2023
1 parent 2d9a384 commit 2472c1f
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 128 deletions.

Large diffs are not rendered by default.

Expand Up @@ -57,6 +57,7 @@ const char kHistogramPrerenderWorstUserInteractionLatencyMaxEventDuration[] =
"PageLoad.InteractiveTiming.WorstUserInteractionLatency.MaxEventDuration."
"Prerender";

// This metric is used for debugging https://crbug.com/1379491.
// Intentionally this metric doesn't record observer events per trigger type
// (e.g., SpeculationRules) because some functions can be called before
// `PrerenderPageLoadMetricsObserver::trigger_type_` is set (e.g., when
Expand All @@ -65,6 +66,56 @@ const char kHistogramPrerenderWorstUserInteractionLatencyMaxEventDuration[] =
const char kPageLoadPrerenderObserverEvent[] =
"PageLoad.Internal.Prerender2.ObserverEvent";

// This metric is used for debugging https://crbug.com/1379491.
const char kPageLoadPrerenderForegroundCheckResult[] =
"PageLoad.Internal.Prerender2.ForegroundCheckResult";

namespace {

// This is a copy of WasActivatedInForegroundOptionalEventInForeground() in
// page_load_metrics_util.h but with recording diagnose metrics for
// https://crbug.com/1379491. Please keep this consistent with the function.
bool WasActivatedInForegroundOptionalEventInForeground(
const absl::optional<base::TimeDelta>& event,
const page_load_metrics::PageLoadMetricsObserverDelegate& delegate,
PageLoadPrerenderForegroundCheckEvent event_type) {
auto result = PageLoadPrerenderForegroundCheckResult::kPassed;
if (!delegate.WasPrerenderedThenActivatedInForeground()) {
result = PageLoadPrerenderForegroundCheckResult::kActivatedInBackground;
} else if (!event) {
result = PageLoadPrerenderForegroundCheckResult::kNoEventTime;
} else if (delegate.GetTimeToFirstBackground() &&
delegate.GetTimeToFirstBackground().value() < event.value()) {
result = PageLoadPrerenderForegroundCheckResult::kBackgroundedBeforeEvent;
}

// Make sure that this function is consistent with the original function.
CHECK_EQ(result == PageLoadPrerenderForegroundCheckResult::kPassed,
page_load_metrics::WasActivatedInForegroundOptionalEventInForeground(
event, delegate));

std::string histogram_name = kPageLoadPrerenderForegroundCheckResult;
switch (event_type) {
case PageLoadPrerenderForegroundCheckEvent::kFirstPaint:
histogram_name += ".FirstPaint";
break;
case PageLoadPrerenderForegroundCheckEvent::kFirstContentfulPaint:
histogram_name += ".FirstContentfulPaint";
break;
case PageLoadPrerenderForegroundCheckEvent::kFirstInputDelay:
histogram_name += ".FirstInputDelay";
break;
case PageLoadPrerenderForegroundCheckEvent::kLargestContentfulPaint:
histogram_name += ".LargestContentfulPaint";
break;
}
base::UmaHistogramEnumeration(histogram_name, result);

return result == PageLoadPrerenderForegroundCheckResult::kPassed;
}

} // namespace

} // namespace internal

PrerenderPageLoadMetricsObserver::PrerenderPageLoadMetricsObserver() = default;
Expand Down Expand Up @@ -149,8 +200,9 @@ void PrerenderPageLoadMetricsObserver::OnFirstPaintInPage(
internal::kPageLoadPrerenderObserverEvent,
internal::PageLoadPrerenderObserverEvent::kOnFirstPaintInPage);

if (!WasActivatedInForegroundOptionalEventInForeground(
timing.paint_timing->first_paint, GetDelegate())) {
if (!internal::WasActivatedInForegroundOptionalEventInForeground(
timing.paint_timing->first_paint, GetDelegate(),
internal::PageLoadPrerenderForegroundCheckEvent::kFirstPaint)) {
return;
}
base::UmaHistogramCustomTimes(
Expand All @@ -166,8 +218,10 @@ void PrerenderPageLoadMetricsObserver::OnFirstContentfulPaintInPage(
internal::kPageLoadPrerenderObserverEvent,
internal::PageLoadPrerenderObserverEvent::kOnFirstContentfulPaintInPage);

if (!WasActivatedInForegroundOptionalEventInForeground(
timing.paint_timing->first_contentful_paint, GetDelegate())) {
if (!internal::WasActivatedInForegroundOptionalEventInForeground(
timing.paint_timing->first_contentful_paint, GetDelegate(),
internal::PageLoadPrerenderForegroundCheckEvent::
kFirstContentfulPaint)) {
return;
}
base::TimeDelta activation_to_fcp =
Expand All @@ -189,8 +243,9 @@ void PrerenderPageLoadMetricsObserver::OnFirstInputInPage(
internal::kPageLoadPrerenderObserverEvent,
internal::PageLoadPrerenderObserverEvent::kOnFirstInputInPage);

if (!WasActivatedInForegroundOptionalEventInForeground(
timing.interactive_timing->first_input_timestamp, GetDelegate())) {
if (!internal::WasActivatedInForegroundOptionalEventInForeground(
timing.interactive_timing->first_input_timestamp, GetDelegate(),
internal::PageLoadPrerenderForegroundCheckEvent::kFirstInputDelay)) {
return;
}

Expand Down Expand Up @@ -256,8 +311,10 @@ void PrerenderPageLoadMetricsObserver::RecordSessionEndHistograms(
.GetLargestContentfulPaintHandler()
.MergeMainFrameAndSubframes();
if (largest_contentful_paint.ContainsValidTime() &&
WasActivatedInForegroundOptionalEventInForeground(
largest_contentful_paint.Time(), GetDelegate())) {
internal::WasActivatedInForegroundOptionalEventInForeground(
largest_contentful_paint.Time(), GetDelegate(),
internal::PageLoadPrerenderForegroundCheckEvent::
kLargestContentfulPaint)) {
base::TimeDelta activation_to_lcp =
largest_contentful_paint.Time().value() -
main_frame_timing.activation_start.value();
Expand Down
Expand Up @@ -50,6 +50,25 @@ enum class PageLoadPrerenderObserverEvent {
kMaxValue = kRecordNormalizedResponsivenessMetrics,
};

extern const char kPageLoadPrerenderForegroundCheckResult[];

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class PageLoadPrerenderForegroundCheckResult {
kActivatedInBackground = 0,
kNoEventTime = 1,
kBackgroundedBeforeEvent = 2,
kPassed = 3,
kMaxValue = kPassed
};

enum class PageLoadPrerenderForegroundCheckEvent {
kFirstPaint,
kFirstContentfulPaint,
kFirstInputDelay,
kLargestContentfulPaint
};

} // namespace internal

// Prerender2 (content/browser/preloading/prerender/README.md):
Expand Down
Expand Up @@ -123,6 +123,8 @@ bool WasStartedInForegroundOptionalEventInForeground(
event.value() <= delegate.GetTimeToFirstBackground().value());
}

// There is a copy of this function in prerender_page_load_metrics_observer.cc.
// Please keep this consistent with the function.
bool WasActivatedInForegroundOptionalEventInForeground(
const absl::optional<base::TimeDelta>& event,
const PageLoadMetricsObserverDelegate& delegate) {
Expand Down
25 changes: 21 additions & 4 deletions components/page_load_metrics/browser/page_load_tracker.cc
Expand Up @@ -40,6 +40,8 @@ const char kPageLoadCompletedAfterAppBackground[] =
const char kPageLoadPrerender2Event[] = "PageLoad.Internal.Prerender2.Event";
const char kPageLoadStartedInForeground[] =
"PageLoad.Internal.NavigationStartedInForeground";
const char kPageLoadPrerender2VisibilityAtActivation[] =
"PageLoad.Internal.Prerender2.VisibilityAtActivation";
const char kPageLoadTrackerPageType[] = "PageLoad.Internal.PageType";

} // namespace internal
Expand Down Expand Up @@ -486,10 +488,25 @@ void PageLoadTracker::DidActivatePrerenderedPage(
source_id_ = ukm::ConvertToSourceId(navigation_handle->GetNavigationId(),
ukm::SourceIdType::NAVIGATION_ID);

if (GetWebContents()->GetVisibility() == content::Visibility::VISIBLE) {
visibility_at_activation_ = PageVisibility::kForeground;
} else {
visibility_at_activation_ = PageVisibility::kBackground;
switch (GetWebContents()->GetVisibility()) {
case content::Visibility::HIDDEN:
visibility_at_activation_ = PageVisibility::kBackground;
base::UmaHistogramEnumeration(
internal::kPageLoadPrerender2VisibilityAtActivation,
internal::VisibilityAtActivation::kHidden);
break;
case content::Visibility::OCCLUDED:
visibility_at_activation_ = PageVisibility::kBackground;
base::UmaHistogramEnumeration(
internal::kPageLoadPrerender2VisibilityAtActivation,
internal::VisibilityAtActivation::kOccluded);
break;
case content::Visibility::VISIBLE:
visibility_at_activation_ = PageVisibility::kForeground;
base::UmaHistogramEnumeration(
internal::kPageLoadPrerender2VisibilityAtActivation,
internal::VisibilityAtActivation::kVisible);
break;
}

for (const auto& observer : observers_)
Expand Down
10 changes: 10 additions & 0 deletions components/page_load_metrics/browser/page_load_tracker.h
Expand Up @@ -66,8 +66,18 @@ extern const char kErrorEvents[];
extern const char kPageLoadCompletedAfterAppBackground[];
extern const char kPageLoadPrerender2Event[];
extern const char kPageLoadStartedInForeground[];
extern const char kPageLoadPrerender2VisibilityAtActivation[];
extern const char kPageLoadTrackerPageType[];

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class VisibilityAtActivation {
kHidden = 0,
kOccluded = 1,
kVisible = 2,
kMaxValue = kVisible
};

} // namespace internal

// These errors are internal to the page_load_metrics subsystem and do not
Expand Down
13 changes: 13 additions & 0 deletions tools/metrics/histograms/enums.xml
Expand Up @@ -76697,6 +76697,13 @@ Called by update_net_trust_anchors.py.-->
<int value="1" label="Prerender Activation Navigation"/>
</enum>

<enum name="PageLoadPrerenderForegroundCheckResult">
<int value="0" label="Activated in background"/>
<int value="1" label="No event time"/>
<int value="2" label="Backgrounded before the event"/>
<int value="3" label="Passed the check"/>
</enum>

<enum name="PageLoadPrerenderObserverEvent">
<int value="0" label="OnPrerenderStart"/>
<int value="1" label="DidActivatePrerenderedPage"/>
Expand All @@ -76710,6 +76717,12 @@ Called by update_net_trust_anchors.py.-->
<int value="9" label="RecordNormalizedResponsivenessMetrics"/>
</enum>

<enum name="PageLoadPrerenderVisibilityAtActivation">
<int value="0" label="Hidden"/>
<int value="1" label="Occluded"/>
<int value="2" label="Visible"/>
</enum>

<enum name="PageLoadTimingStatus">
<summary>Status of PageLoadTimings received from the render process</summary>
<int value="0" label="Valid"/>
Expand Down
27 changes: 27 additions & 0 deletions tools/metrics/histograms/metadata/page/histograms.xml
Expand Up @@ -2393,6 +2393,23 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>

<histogram
name="PageLoad.Internal.Prerender2.ForegroundCheckResult.{PageLoadPrerenderForegroundCheckEvent}"
enum="PageLoadPrerenderForegroundCheckResult" expires_after="2023-07-26">
<owner>nhiroki@chromium.org</owner>
<owner>src/content/browser/preloading/prerender/OWNERS</owner>
<summary>
Records results of the foreground check per event type in
PrerenderPageLoadMetricsObserver.
</summary>
<token key="PageLoadPrerenderForegroundCheckEvent">
<variant name="FirstContentfulPaint"/>
<variant name="FirstInputDelay"/>
<variant name="FirstPaint"/>
<variant name="LargestContentfulPaint"/>
</token>
</histogram>

<histogram name="PageLoad.Internal.Prerender2.ObserverEvent"
enum="PageLoadPrerenderObserverEvent" expires_after="2023-07-26">
<owner>nhiroki@chromium.org</owner>
Expand All @@ -2404,6 +2421,16 @@ chromium-metrics-reviews@google.com.
</summary>
</histogram>

<histogram name="PageLoad.Internal.Prerender2.VisibilityAtActivation"
enum="PageLoadPrerenderVisibilityAtActivation" expires_after="2023-07-26">
<owner>nhiroki@chromium.org</owner>
<owner>src/content/browser/preloading/prerender/OWNERS</owner>
<summary>
Records the visibility of an initiator page in PageLoadTracker when a
prerendered page gets activated.
</summary>
</histogram>

<histogram name="PageLoad.Internal.Renderer.PresentationTime.DeltaFromSwapTime"
units="ms" expires_after="2023-06-04">
<owner>jonross@chromium.org</owner>
Expand Down

0 comments on commit 2472c1f

Please sign in to comment.