Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: chrome/browser/page_load_metrics/page_load_tracker.h

Issue 2904533002: Factor management of metrics updates into its own class. (Closed)
Patch Set: cleanup Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ 5 #ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_
6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ 6 #define CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_
7 7
8 #include <memory> 8 #include <memory>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/optional.h" 12 #include "base/optional.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h" 14 #include "chrome/browser/page_load_metrics/page_load_metrics_observer.h"
15 #include "chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h "
15 #include "chrome/browser/page_load_metrics/user_input_tracker.h" 16 #include "chrome/browser/page_load_metrics/user_input_tracker.h"
16 #include "chrome/common/page_load_metrics/page_load_timing.h" 17 #include "chrome/common/page_load_metrics/page_load_timing.h"
17 #include "content/public/browser/global_request_id.h" 18 #include "content/public/browser/global_request_id.h"
18 #include "content/public/browser/web_contents_observer.h" 19 #include "content/public/browser/web_contents_observer.h"
19 #include "ui/base/page_transition_types.h" 20 #include "ui/base/page_transition_types.h"
20 21
21 class GURL; 22 class GURL;
22 23
23 namespace blink { 24 namespace blink {
24 class WebInputEvent; 25 class WebInputEvent;
(...skipping 11 matching lines...) Expand all
36 37
37 namespace internal { 38 namespace internal {
38 39
39 extern const char kErrorEvents[]; 40 extern const char kErrorEvents[];
40 extern const char kAbortChainSizeReload[]; 41 extern const char kAbortChainSizeReload[];
41 extern const char kAbortChainSizeForwardBack[]; 42 extern const char kAbortChainSizeForwardBack[];
42 extern const char kAbortChainSizeNewNavigation[]; 43 extern const char kAbortChainSizeNewNavigation[];
43 extern const char kAbortChainSizeNoCommit[]; 44 extern const char kAbortChainSizeNoCommit[];
44 extern const char kAbortChainSizeSameURL[]; 45 extern const char kAbortChainSizeSameURL[];
45 extern const char kPageLoadCompletedAfterAppBackground[]; 46 extern const char kPageLoadCompletedAfterAppBackground[];
46 extern const char kPageLoadTimingStatus[];
47
48 // Used to track the status of PageLoadTimings received from the render process.
49 //
50 // If you add elements to this enum, make sure you update the enum value in
51 // histograms.xml. Only add elements to the end to prevent inconsistencies
52 // between versions.
53 enum PageLoadTimingStatus {
54 // The PageLoadTiming is valid (all data within the PageLoadTiming is
55 // consistent with expectations).
56 VALID,
57
58 // All remaining status codes are for invalid PageLoadTimings.
59
60 // The PageLoadTiming was empty.
61 INVALID_EMPTY_TIMING,
62
63 // The PageLoadTiming had a null navigation_start.
64 INVALID_NULL_NAVIGATION_START,
65
66 // Script load or execution durations in the PageLoadTiming were too long.
67 INVALID_SCRIPT_LOAD_LONGER_THAN_PARSE,
68 INVALID_SCRIPT_EXEC_LONGER_THAN_PARSE,
69 INVALID_SCRIPT_LOAD_DOC_WRITE_LONGER_THAN_SCRIPT_LOAD,
70 INVALID_SCRIPT_EXEC_DOC_WRITE_LONGER_THAN_SCRIPT_EXEC,
71
72 // The order of two events in the PageLoadTiming was invalid. Either the first
73 // wasn't present when the second was present, or the second was reported as
74 // happening before the first.
75 INVALID_ORDER_RESPONSE_START_PARSE_START,
76 INVALID_ORDER_PARSE_START_PARSE_STOP,
77 INVALID_ORDER_PARSE_STOP_DOM_CONTENT_LOADED,
78 INVALID_ORDER_DOM_CONTENT_LOADED_LOAD,
79 INVALID_ORDER_PARSE_START_FIRST_LAYOUT,
80 INVALID_ORDER_FIRST_LAYOUT_FIRST_PAINT,
81 INVALID_ORDER_FIRST_PAINT_FIRST_TEXT_PAINT,
82 INVALID_ORDER_FIRST_PAINT_FIRST_IMAGE_PAINT,
83 INVALID_ORDER_FIRST_PAINT_FIRST_CONTENTFUL_PAINT,
84 INVALID_ORDER_FIRST_PAINT_FIRST_MEANINGFUL_PAINT,
85
86 // New values should be added before this final entry.
87 LAST_PAGE_LOAD_TIMING_STATUS
88 };
89 47
90 } // namespace internal 48 } // namespace internal
91 49
92 // These errors are internal to the page_load_metrics subsystem and do not 50 // These errors are internal to the page_load_metrics subsystem and do not
93 // reflect actual errors that occur during a page load. 51 // reflect actual errors that occur during a page load.
94 // 52 //
95 // If you add elements to this enum, make sure you update the enum 53 // If you add elements to this enum, make sure you update the enum
96 // value in histograms.xml. Only add elements to the end to prevent 54 // value in histograms.xml. Only add elements to the end to prevent
97 // inconsistencies between versions. 55 // inconsistencies between versions.
98 enum InternalErrorLoadEvent { 56 enum InternalErrorLoadEvent {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 // to access them. 140 // to access them.
183 void RecordInternalError(InternalErrorLoadEvent event); 141 void RecordInternalError(InternalErrorLoadEvent event);
184 PageEndReason EndReasonForPageTransition(ui::PageTransition transition); 142 PageEndReason EndReasonForPageTransition(ui::PageTransition transition);
185 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); 143 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url);
186 bool IsNavigationUserInitiated(content::NavigationHandle* handle); 144 bool IsNavigationUserInitiated(content::NavigationHandle* handle);
187 145
188 // This class tracks a given page load, starting from navigation start / 146 // This class tracks a given page load, starting from navigation start /
189 // provisional load, until a new navigation commits or the navigation fails. 147 // provisional load, until a new navigation commits or the navigation fails.
190 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as 148 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as
191 // well as a committed PageLoadTracker. 149 // well as a committed PageLoadTracker.
192 class PageLoadTracker { 150 class PageLoadTracker : public PageLoadMetricsUpdateDispatcher::Client {
193 public: 151 public:
194 // Caller must guarantee that the embedder_interface pointer outlives this 152 // Caller must guarantee that the embedder_interface pointer outlives this
195 // class. The PageLoadTracker must not hold on to 153 // class. The PageLoadTracker must not hold on to
196 // currently_committed_load_or_null or navigation_handle beyond the scope of 154 // currently_committed_load_or_null or navigation_handle beyond the scope of
197 // the constructor. 155 // the constructor.
198 PageLoadTracker(bool in_foreground, 156 PageLoadTracker(bool in_foreground,
199 PageLoadMetricsEmbedderInterface* embedder_interface, 157 PageLoadMetricsEmbedderInterface* embedder_interface,
200 const GURL& currently_committed_url, 158 const GURL& currently_committed_url,
201 content::NavigationHandle* navigation_handle, 159 content::NavigationHandle* navigation_handle,
202 UserInitiatedInfo user_initiated_info, 160 UserInitiatedInfo user_initiated_info,
203 int aborted_chain_size, 161 int aborted_chain_size,
204 int aborted_chain_size_same_url); 162 int aborted_chain_size_same_url);
205 ~PageLoadTracker(); 163 ~PageLoadTracker() override;
164
165 // PageLoadMetricsUpdateDispatcher::Client implementation:
166 void OnTimingChanged() override;
167 void OnMainFrameMetadataChanged() override;
168 void OnSubframeMetadataChanged() override;
169
206 void Redirect(content::NavigationHandle* navigation_handle); 170 void Redirect(content::NavigationHandle* navigation_handle);
207 void WillProcessNavigationResponse( 171 void WillProcessNavigationResponse(
208 content::NavigationHandle* navigation_handle); 172 content::NavigationHandle* navigation_handle);
209 void Commit(content::NavigationHandle* navigation_handle); 173 void Commit(content::NavigationHandle* navigation_handle);
210 void DidCommitSameDocumentNavigation( 174 void DidCommitSameDocumentNavigation(
211 content::NavigationHandle* navigation_handle); 175 content::NavigationHandle* navigation_handle);
212 void DidFinishSubFrameNavigation( 176 void DidFinishSubFrameNavigation(
213 content::NavigationHandle* navigation_handle); 177 content::NavigationHandle* navigation_handle);
214 void FailedProvisionalLoad(content::NavigationHandle* navigation_handle, 178 void FailedProvisionalLoad(content::NavigationHandle* navigation_handle,
215 base::TimeTicks failed_load_time); 179 base::TimeTicks failed_load_time);
216 void WebContentsHidden(); 180 void WebContentsHidden();
217 void WebContentsShown(); 181 void WebContentsShown();
218 182
219 void OnInputEvent(const blink::WebInputEvent& event); 183 void OnInputEvent(const blink::WebInputEvent& event);
220 184
221 // Flush any buffered metrics, as part of the metrics subsystem persisting 185 // Flush any buffered metrics, as part of the metrics subsystem persisting
222 // metrics as the application goes into the background. The application may be 186 // metrics as the application goes into the background. The application may be
223 // killed at any time after this method is invoked without further 187 // killed at any time after this method is invoked without further
224 // notification. 188 // notification.
225 void FlushMetricsOnAppEnterBackground(); 189 void FlushMetricsOnAppEnterBackground();
226 190
227 void NotifyClientRedirectTo(const PageLoadTracker& destination); 191 void NotifyClientRedirectTo(const PageLoadTracker& destination);
228 192
229 void UpdateTiming(const mojom::PageLoadTiming& timing, 193 void UpdateTiming(content::RenderFrameHost* render_frame_host,
194 const mojom::PageLoadTiming& timing,
230 const mojom::PageLoadMetadata& metadata); 195 const mojom::PageLoadMetadata& metadata);
231 196
232 void UpdateSubFrameTiming(content::RenderFrameHost* render_frame_host,
233 const mojom::PageLoadTiming& new_timing,
234 const mojom::PageLoadMetadata& new_metadata);
235
236 // Update metadata for child frames. Updates for child frames arrive
237 // separately from updates for the main frame, so aren't included in
238 // UpdateTiming.
239 void UpdateSubFrameMetadata(const mojom::PageLoadMetadata& subframe_metadata);
240
241 void OnStartedResource( 197 void OnStartedResource(
242 const ExtraRequestStartInfo& extra_request_started_info); 198 const ExtraRequestStartInfo& extra_request_started_info);
243 199
244 void OnLoadedResource( 200 void OnLoadedResource(
245 const ExtraRequestCompleteInfo& extra_request_complete_info); 201 const ExtraRequestCompleteInfo& extra_request_complete_info);
246 202
247 // Signals that we should stop tracking metrics for the associated page load. 203 // Signals that we should stop tracking metrics for the associated page load.
248 // We may stop tracking a page load if it doesn't meet the criteria for 204 // We may stop tracking a page load if it doesn't meet the criteria for
249 // tracking metrics in DidFinishNavigation. 205 // tracking metrics in DidFinishNavigation.
250 void StopTracking(); 206 void StopTracking();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 // and is simpler than other feasible methods. See https://goo.gl/WKRG98. 238 // and is simpler than other feasible methods. See https://goo.gl/WKRG98.
283 bool IsLikelyProvisionalAbort(base::TimeTicks abort_cause_time) const; 239 bool IsLikelyProvisionalAbort(base::TimeTicks abort_cause_time) const;
284 240
285 bool MatchesOriginalNavigation(content::NavigationHandle* navigation_handle); 241 bool MatchesOriginalNavigation(content::NavigationHandle* navigation_handle);
286 242
287 bool did_commit() const { return did_commit_; } 243 bool did_commit() const { return did_commit_; }
288 const GURL& url() const { return url_; } 244 const GURL& url() const { return url_; }
289 245
290 base::TimeTicks navigation_start() const { return navigation_start_; } 246 base::TimeTicks navigation_start() const { return navigation_start_; }
291 247
292 PageLoadExtraInfo ComputePageLoadExtraInfo(); 248 PageLoadExtraInfo ComputePageLoadExtraInfo() const;
293 249
294 ui::PageTransition page_transition() const { return page_transition_; } 250 ui::PageTransition page_transition() const { return page_transition_; }
295 251
296 UserInitiatedInfo user_initiated_info() const { return user_initiated_info_; } 252 UserInitiatedInfo user_initiated_info() const { return user_initiated_info_; }
297 253
298 UserInputTracker* input_tracker() { return &input_tracker_; } 254 UserInputTracker* input_tracker() { return &input_tracker_; }
299 255
300 // Whether this PageLoadTracker has a navigation GlobalRequestID that matches 256 // Whether this PageLoadTracker has a navigation GlobalRequestID that matches
301 // the given request_id. This method will return false before 257 // the given request_id. This method will return false before
302 // WillProcessNavigationResponse has been invoked, as PageLoadTracker doesn't 258 // WillProcessNavigationResponse has been invoked, as PageLoadTracker doesn't
303 // know its GlobalRequestID until WillProcessNavigationResponse has been 259 // know its GlobalRequestID until WillProcessNavigationResponse has been
304 // invoked. 260 // invoked.
305 bool HasMatchingNavigationRequestID( 261 bool HasMatchingNavigationRequestID(
306 const content::GlobalRequestID& request_id) const; 262 const content::GlobalRequestID& request_id) const;
307 263
308 // Invoked when a media element starts playing. 264 // Invoked when a media element starts playing.
309 void MediaStartedPlaying( 265 void MediaStartedPlaying(
310 const content::WebContentsObserver::MediaPlayerInfo& video_type, 266 const content::WebContentsObserver::MediaPlayerInfo& video_type,
311 bool is_in_main_frame); 267 bool is_in_main_frame);
312 268
313 // Invoked on navigations where a navigation delay was added by the 269 // Invoked on navigations where a navigation delay was added by the
314 // DelayNavigationThrottle. This is a temporary method that will be removed 270 // DelayNavigationThrottle. This is a temporary method that will be removed
315 // once the experiment is complete. 271 // once the experiment is complete.
316 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay, 272 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay,
317 base::TimeDelta actual_delay); 273 base::TimeDelta actual_delay);
318 274
319 private: 275 private:
320 using FrameTreeNodeId = int;
321
322 // This function converts a TimeTicks value taken in the browser process 276 // This function converts a TimeTicks value taken in the browser process
323 // to navigation_start_ if: 277 // to navigation_start_ if:
324 // - base::TimeTicks is not comparable across processes because the clock 278 // - base::TimeTicks is not comparable across processes because the clock
325 // is not system wide monotonic. 279 // is not system wide monotonic.
326 // - *event_time < navigation_start_ 280 // - *event_time < navigation_start_
327 void ClampBrowserTimestampIfInterProcessTimeTickSkew( 281 void ClampBrowserTimestampIfInterProcessTimeTickSkew(
328 base::TimeTicks* event_time); 282 base::TimeTicks* event_time);
329 283
330 void UpdatePageEndInternal(PageEndReason page_end_reason, 284 void UpdatePageEndInternal(PageEndReason page_end_reason,
331 UserInitiatedInfo user_initiated_info, 285 UserInitiatedInfo user_initiated_info,
332 base::TimeTicks timestamp, 286 base::TimeTicks timestamp,
333 bool is_certainly_browser_timestamp); 287 bool is_certainly_browser_timestamp);
334 288
335 // If |final_navigation| is null, then this is an "unparented" abort chain, 289 // If |final_navigation| is null, then this is an "unparented" abort chain,
336 // and represents a sequence of provisional aborts that never ends with a 290 // and represents a sequence of provisional aborts that never ends with a
337 // committed load. 291 // committed load.
338 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); 292 void LogAbortChainHistograms(content::NavigationHandle* final_navigation);
339 293
340 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); 294 void MaybeUpdateURL(content::NavigationHandle* navigation_handle);
341 295
342 // Merge values from |new_paint_timing| into |merged_page_timing_|, offsetting
343 // any new timings by the |navigation_start_offset|.
344 void MergePaintTiming(base::TimeDelta navigation_start_offset,
345 const mojom::PaintTiming& new_paint_timing,
346 bool is_main_frame);
347
348 void DispatchTimingUpdates();
349
350 UserInputTracker input_tracker_; 296 UserInputTracker input_tracker_;
351 297
352 // Whether we stopped tracking this navigation after it was initiated. We may 298 // Whether we stopped tracking this navigation after it was initiated. We may
353 // stop tracking a navigation if it doesn't meet the criteria for tracking 299 // stop tracking a navigation if it doesn't meet the criteria for tracking
354 // metrics in DidFinishNavigation. 300 // metrics in DidFinishNavigation.
355 bool did_stop_tracking_; 301 bool did_stop_tracking_;
356 302
357 // Whether the application went into the background when this PageLoadTracker 303 // Whether the application went into the background when this PageLoadTracker
358 // was active. This is a temporary boolean for UMA tracking. 304 // was active. This is a temporary boolean for UMA tracking.
359 bool app_entered_background_; 305 bool app_entered_background_;
(...skipping 29 matching lines...) Expand all
389 335
390 base::TimeTicks page_end_time_; 336 base::TimeTicks page_end_time_;
391 337
392 // We record separate metrics for events that occur after a background, 338 // We record separate metrics for events that occur after a background,
393 // because metrics like layout/paint are delayed artificially 339 // because metrics like layout/paint are delayed artificially
394 // when they occur in the background. 340 // when they occur in the background.
395 base::TimeTicks background_time_; 341 base::TimeTicks background_time_;
396 base::TimeTicks foreground_time_; 342 base::TimeTicks foreground_time_;
397 bool started_in_foreground_; 343 bool started_in_foreground_;
398 344
399 // PageLoadTiming for the currently tracked page. The fields in |paint_timing|
400 // are merged across all frames in the document. All other fields are for the
401 // main frame document.
402 mojom::PageLoadTimingPtr merged_page_timing_;
403 mojom::PageLoadTimingPtr last_dispatched_merged_page_timing_; 345 mojom::PageLoadTimingPtr last_dispatched_merged_page_timing_;
404 346
405 mojom::PageLoadMetadata main_frame_metadata_;
406 mojom::PageLoadMetadataPtr last_dispatched_main_frame_metadata_;
407
408 mojom::PageLoadMetadata subframe_metadata_;
409
410 ui::PageTransition page_transition_; 347 ui::PageTransition page_transition_;
411 348
412 base::Optional<content::GlobalRequestID> navigation_request_id_; 349 base::Optional<content::GlobalRequestID> navigation_request_id_;
413 350
414 // Whether this page load was user initiated. 351 // Whether this page load was user initiated.
415 UserInitiatedInfo user_initiated_info_; 352 UserInitiatedInfo user_initiated_info_;
416 353
417 // This is a subtle member. If a provisional load A gets aborted by 354 // This is a subtle member. If a provisional load A gets aborted by
418 // provisional load B, which gets aborted by C that eventually commits, then 355 // provisional load B, which gets aborted by C that eventually commits, then
419 // there exists an abort chain of length 2, starting at A's navigation_start. 356 // there exists an abort chain of length 2, starting at A's navigation_start.
420 // This is useful because it allows histograming abort chain lengths based on 357 // This is useful because it allows histograming abort chain lengths based on
421 // what the last load's transition type is. i.e. holding down F-5 to spam 358 // what the last load's transition type is. i.e. holding down F-5 to spam
422 // reload will produce a long chain with the RELOAD transition. 359 // reload will produce a long chain with the RELOAD transition.
423 const int aborted_chain_size_; 360 const int aborted_chain_size_;
424 361
425 // This member counts consecutive provisional aborts that share a url. It will 362 // This member counts consecutive provisional aborts that share a url. It will
426 // always be less than or equal to |aborted_chain_size_|. 363 // always be less than or equal to |aborted_chain_size_|.
427 const int aborted_chain_size_same_url_; 364 const int aborted_chain_size_same_url_;
428 365
429 // Interface to chrome features. Must outlive the class. 366 // Interface to chrome features. Must outlive the class.
430 PageLoadMetricsEmbedderInterface* const embedder_interface_; 367 PageLoadMetricsEmbedderInterface* const embedder_interface_;
431 368
432 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; 369 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_;
433 370
434 // Navigation start offsets for the most recently committed document in each 371 PageLoadMetricsUpdateDispatcher metrics_update_dispatcher_;
435 // frame.
436 std::map<FrameTreeNodeId, base::TimeDelta> subframe_navigation_start_offset_;
437 372
438 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); 373 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker);
439 }; 374 };
440 375
441 } // namespace page_load_metrics 376 } // namespace page_load_metrics
442 377
443 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ 378 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698