File: page_load_metrics_util.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (271 lines) | stat: -rw-r--r-- 11,793 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_UTIL_H_
#define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_UTIL_H_

#include <cstdint>
#include <optional>
#include <string_view>

#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
#include "components/page_load_metrics/common/page_load_metrics_util.h"
#include "components/page_load_metrics/common/page_visit_final_status.h"
#include "third_party/blink/public/common/loader/loading_behavior_flag.h"
#include "url/gurl.h"

// Up to 10 minutes, with 100 buckets.
#define PAGE_LOAD_HISTOGRAM(name, sample)                             \
  base::UmaHistogramCustomTimes(name, sample, base::Milliseconds(10), \
                                base::Minutes(10), 100)

// 1 ms to 1 minute, with 100 buckets.
#define PAGE_LOAD_SHORT_HISTOGRAM(name, sample)                      \
  base::UmaHistogramCustomTimes(name, sample, base::Milliseconds(1), \
                                base::Minutes(1), 100)

// Up to 1 hour, with 100 buckets.
#define PAGE_LOAD_LONG_HISTOGRAM(name, sample)                        \
  base::UmaHistogramCustomTimes(name, sample, base::Milliseconds(10), \
                                base::Hours(1), 100)

// Records |bytes| to |histogram_name| in kilobytes (i.e., bytes / 1024).
#define PAGE_BYTES_HISTOGRAM(histogram_name, bytes) \
  base::UmaHistogramCustomCounts(                   \
      histogram_name, static_cast<int>((bytes) / 1024), 1, 500 * 1024, 50)

// Up to 1 minute with 50 buckets.
#define INPUT_DELAY_HISTOGRAM(name, sample)                          \
  base::UmaHistogramCustomTimes(name, sample, base::Milliseconds(1), \
                                base::Seconds(60), 50)

#define PAGE_RESOURCE_COUNT_HISTOGRAM UMA_HISTOGRAM_COUNTS_10000

namespace page_load_metrics {

class PageLoadMetricsObserverDelegate;

namespace mojom {
class PageLoadTiming;
}

// Reasons a page load can be aborted.
enum PageAbortReason {
  // Represents no abort.
  ABORT_NONE,

  // The page was reloaded, possibly by the user.
  ABORT_RELOAD,

  // The page was navigated away from, via a back or forward navigation.
  ABORT_FORWARD_BACK,

  // If the page load is replaced by a new navigation. This includes link
  // clicks, typing in the omnibox (not a reload), and form submissions.
  ABORT_NEW_NAVIGATION,

  // The page load was stopped (e.g. the user presses the stop X button).
  ABORT_STOP,

  // Page load ended due to closing the tab or browser.
  ABORT_CLOSE,

  // The page load was backgrounded, e.g. the browser was minimized or the user
  // switched tabs. Note that the same page may be foregrounded in the future,
  // so this is not a 'terminal' abort type.
  ABORT_BACKGROUND,

  // We don't know why the page load ended. This is the value we assign to a
  // terminated provisional load if the only signal we get is the load finished
  // without committing, either without error or with net::ERR_ABORTED.
  ABORT_OTHER
};

// Information related to a page load abort.
struct PageAbortInfo {
  PageAbortInfo()
      : reason(ABORT_NONE),
        user_initiated_info(UserInitiatedInfo::NotUserInitiated()) {}
  PageAbortInfo(PageAbortReason reason,
                UserInitiatedInfo user_initiated_info,
                base::TimeDelta time_to_abort)
      : reason(reason),
        user_initiated_info(user_initiated_info),
        time_to_abort(time_to_abort) {}

  // The reason / cause for the abort.
  const PageAbortReason reason;

  // The fields below are only valid if reason != ABORT_NONE.

  // Information about whether the abort was initiated by a user.
  const UserInitiatedInfo user_initiated_info;

  // The time from navigation start to the time the page load was aborted.
  const base::TimeDelta time_to_abort;
};

// UMA histogram function for logging the max cumulative shift score. Adjusts
// the layout shift score to 10000x for better bucketing at the low end in UMA.
void UmaMaxCumulativeShiftScoreHistogram10000x(
    const std::string& name,
    const page_load_metrics::NormalizedCLSData& normalized_cls_data);

// Returns true if:
// - We have timing information for the event.
// - The page load started while the page was in the foreground.
// - The event occurred prior to the page being moved to the background.
// When a page is backgrounded, some events (e.g. paint) are delayed. Since
// these data points can skew the mean, they should not be mixed with timing
// events that occurred in the foreground.
// If the event time delta and background time delta are equal, we still
// consider the event to be logged in the foreground histogram since any
// background specific handling would not yet have been applied to that event.
bool WasStartedInForegroundOptionalEventInForeground(
    const std::optional<base::TimeDelta>& event,
    const PageLoadMetricsObserverDelegate& delegate);

// Returns true if:
// - We have timing information for the event.
// - The page load was prerendered, and was later activated by a navigation that
//   started in the foreground.
// - The event occurred prior to the page being moved to the background.
bool WasActivatedInForegroundOptionalEventInForeground(
    const std::optional<base::TimeDelta>& event,
    const PageLoadMetricsObserverDelegate& delegate);

bool WasStartedInForegroundOptionalEventInForegroundAfterBackForwardCacheRestore(
    const std::optional<base::TimeDelta>& event,
    const PageLoadMetricsObserverDelegate& delegate,
    size_t index);

// Returns true if:
// - We have timing information for the event.
// - The page load started in the background.
// - Moved to the foreground prior to the event.
// - Not moved back to the background prior to the event.
bool WasStartedInBackgroundOptionalEventInForeground(
    const std::optional<base::TimeDelta>& event,
    const PageLoadMetricsObserverDelegate& delegate);

// Returns true if |delegate| started in the foreground or became foregrounded
// at some point in time.
bool WasInForeground(const PageLoadMetricsObserverDelegate& delegate);

// Returns (navigation start origined) "non prerendering background start" if
// it exists, or nullopt. Here, "non prerendering background start" is the
// minimum timing `x` satisfying:
//
// - The page is background at `x`; and
// - `x` as TimeDelta is greater than or equal to navigation start (resp.
//   activation start) if the page is not prerendered (resp. is prerendered).
//
// Note that this can be different from the return value of
// `PageLoadMetricsObserverDelegate::GetTimeToFirstBackground`.
std::optional<base::TimeDelta> GetNonPrerenderingBackgroundStartTiming(
    const PageLoadMetricsObserverDelegate& delegate);

// Returns true iff event occurred in prerendered before activation or before
// background start.
//
// Precondition: `HasInvalidActivationStart` must not hold.
// In this case, arbitrary value will be returned.
bool EventOccurredBeforeNonPrerenderingBackgroundStart(
    const PageLoadMetricsObserverDelegate& delegate,
    const base::TimeDelta& event);
bool EventOccurredBeforeNonPrerenderingBackgroundStart(
    const PageLoadMetricsObserverDelegate& delegate,
    const page_load_metrics::mojom::PageLoadTiming& timing,
    const base::TimeDelta& event);

// Corrects an event with navigation start origin as navigation/activation
// start origin.
//
// If the page is not prerendered, returns the event as is. If the page is
// prerendered, returns activation start origined time delta. Negative values
// are truncated as zero.
base::TimeDelta CorrectEventAsNavigationOrActivationOrigined(
    const PageLoadMetricsObserverDelegate& delegate,
    const base::TimeDelta& event);
base::TimeDelta CorrectEventAsNavigationOrActivationOrigined(
    const PageLoadMetricsObserverDelegate& delegate,
    const page_load_metrics::mojom::PageLoadTiming& timing,
    const base::TimeDelta& event);

PageAbortInfo GetPageAbortInfo(const PageLoadMetricsObserverDelegate& delegate);

// Get the duration of time that the page spent in the foreground, from
// navigation start until one of the following events:
// * the load of the main resource fails
// * the page load is stopped
// * the tab hosting the page is closed
// * the render process hosting the page goes away
// * a new navigation which later commits is initiated in the same tab
// * the tab hosting the page is backgrounded
std::optional<base::TimeDelta> GetInitialForegroundDuration(
    const PageLoadMetricsObserverDelegate& delegate,
    base::TimeTicks app_background_time);

// zstd content-coded responses.
bool IsZstdUrl(const GURL& url);

// Whether the given query string contains the given component. The query
// parameter should contain the query string of a URL (the portion following
// the question mark, excluding the question mark). The component must fully
// match a component in the query string. For example, 'foo=bar' would match
// the query string 'a=b&foo=bar&c=d' but would not match 'a=b&zzzfoo=bar&c=d'
// since, though foo=bar appears in the query string, the key specified in the
// component 'foo' does not match the full key in the query string
// 'zzzfoo'. For QueryContainsComponent, the component should of the form
// 'key=value'. For QueryContainsComponentPrefix, the component should be of
// the form 'key=' (where the value is not specified).
// Note: The heuristic used by these functions will not find a component at the
// beginning of the query string if the component starts with a delimiter
// character ('?' or '#'). For example, '?foo=bar' will match the query string
// 'a=b&?foo=bar' but not the query string '?foo=bar&a=b'.
bool QueryContainsComponent(std::string_view query, std::string_view component);
bool QueryContainsComponentPrefix(std::string_view query,
                                  std::string_view component);

// Adjusts the layout shift score for UKM.
int64_t LayoutShiftUkmValue(float shift_score);

// Adjusts the layout shift score for UMA.
int32_t LayoutShiftUmaValue(float shift_score);

// Adjusts the layout shift score to 10000x for better bucketing at the low end
// in UMA.
int32_t LayoutShiftUmaValue10000(float shift_score);

// Helper function that determines the final status for a page visit for a given
// PageLoadTiming, records it to the appropriate UKM metric and UMA histogram,
// and returns the status in case the caller needs to use it elsewhere.
// A 'Page Visit' is a user perceived visit to a page, regardless of how the
// page was navigated to. See the UserPerceivedPageVisit event in
// tools/metrics/ukm.xml.
PageVisitFinalStatus RecordPageVisitFinalStatusForTiming(
    const page_load_metrics::mojom::PageLoadTiming& timing,
    const PageLoadMetricsObserverDelegate& delegate,
    ukm::SourceId source_id);

// Returns the ID if `url` contains a URL param where the param name and value
// matches the prefix pattern configured by Finch (the default param name is
// "category" and the prefix pattern is an empty string / will match anything).
// Returns std::nullopt if the param value is not recognized.
//
// For example, if the valid param name  is "cat" and the prefix pattern is
// "pattern", this function may return an ID for (1) but not for (2):
//
// (1) http://a.com?cat=pattern1
// (2) http://b.com?cat=invalid-pattern
//
// UKM Review:
// https://docs.google.com/document/d/1TSbtp5I5Bc1pbAKrrEHfmZlAwgeh6AlgAH7GbDMNPRQ/edit?disco=AAABe5h90jQ
std::optional<uint32_t> GetCategoryIdFromUrl(const GURL& url);

}  // namespace page_load_metrics

#endif  // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_UTIL_H_