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

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

Issue 2859393002: Report page load timing information for child frames. (Closed)
Patch Set: add comment 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/user_input_tracker.h" 15 #include "chrome/browser/page_load_metrics/user_input_tracker.h"
16 #include "chrome/common/page_load_metrics/page_load_timing.h" 16 #include "chrome/common/page_load_metrics/page_load_timing.h"
17 #include "content/public/browser/global_request_id.h" 17 #include "content/public/browser/global_request_id.h"
18 #include "content/public/browser/web_contents_observer.h" 18 #include "content/public/browser/web_contents_observer.h"
19 #include "ui/base/page_transition_types.h" 19 #include "ui/base/page_transition_types.h"
20 20
21 class GURL; 21 class GURL;
22 22
23 namespace blink { 23 namespace blink {
24 class WebInputEvent; 24 class WebInputEvent;
25 } // namespace blink 25 } // namespace blink
26 26
27 namespace content { 27 namespace content {
28 class NavigationHandle; 28 class NavigationHandle;
29 class RenderFrameHost;
29 } // namespace content 30 } // namespace content
30 31
31 namespace page_load_metrics { 32 namespace page_load_metrics {
32 33
33 class PageLoadMetricsEmbedderInterface; 34 class PageLoadMetricsEmbedderInterface;
34 class PageLoadMetricsObserver; 35 class PageLoadMetricsObserver;
35 36
36 namespace internal { 37 namespace internal {
37 38
38 extern const char kErrorEvents[]; 39 extern const char kErrorEvents[];
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // renderer process and the system clock has inter process time tick skew. 146 // renderer process and the system clock has inter process time tick skew.
146 ERR_INTER_PROCESS_TIME_TICK_SKEW, 147 ERR_INTER_PROCESS_TIME_TICK_SKEW,
147 148
148 // At the time a PageLoadTracker was destroyed, we had received neither a 149 // At the time a PageLoadTracker was destroyed, we had received neither a
149 // commit nor a failed provisional load. 150 // commit nor a failed provisional load.
150 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD, 151 ERR_NO_COMMIT_OR_FAILED_PROVISIONAL_LOAD,
151 152
152 // No page load end time was recorded for this page load. 153 // No page load end time was recorded for this page load.
153 ERR_NO_PAGE_LOAD_END_TIME, 154 ERR_NO_PAGE_LOAD_END_TIME,
154 155
155 // Received a timing update from a subframe. 156 // Received a timing update from a subframe (deprecated).
156 ERR_TIMING_IPC_FROM_SUBFRAME, 157 DEPRECATED_ERR_TIMING_IPC_FROM_SUBFRAME,
157 158
158 // A timing IPC was sent from the renderer that contained timing data which 159 // A timing IPC was sent from the renderer that contained timing data which
159 // was inconsistent with our timing data for the currently committed load. 160 // was inconsistent with our timing data for the currently committed load.
160 ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT, 161 ERR_BAD_TIMING_IPC_INVALID_TIMING_DESCENDENT,
161 162
162 // A timing IPC was sent from the renderer that contained loading behavior 163 // A timing IPC was sent from the renderer that contained loading behavior
163 // data which was inconsistent with our loading behavior data for the 164 // data which was inconsistent with our loading behavior data for the
164 // currently committed load. 165 // currently committed load.
165 ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT, 166 ERR_BAD_TIMING_IPC_INVALID_BEHAVIOR_DESCENDENT,
166 167
167 // A timing IPC was sent from the renderer that contained invalid timing data 168 // A timing IPC was sent from the renderer that contained invalid timing data
168 // (e.g. out of order timings, or other issues). 169 // (e.g. out of order timings, or other issues).
169 ERR_BAD_TIMING_IPC_INVALID_TIMING, 170 ERR_BAD_TIMING_IPC_INVALID_TIMING,
170 171
172 // We received an IPC for a subframe when we weren't tracking a committed load
173 // in that frame. This can happen if the frame fails to commit but a document
174 // is created in it from the parent document via document.open().
175 ERR_SUBFRAME_IPC_WITH_NO_RELEVANT_LOAD,
176
177 // We received a navigation start for a child frame that is before the
178 // navigation start of the main frame.
179 ERR_SUBFRAME_NAVIGATION_START_BEFORE_MAIN_FRAME,
180
171 // Add values before this final count. 181 // Add values before this final count.
172 ERR_LAST_ENTRY, 182 ERR_LAST_ENTRY,
173 }; 183 };
174 184
175 // NOTE: these functions are shared by page_load_tracker.cc and 185 // NOTE: these functions are shared by page_load_tracker.cc and
176 // metrics_web_contents_observer.cc. They are declared here to allow both files 186 // metrics_web_contents_observer.cc. They are declared here to allow both files
177 // to access them. 187 // to access them.
178 void RecordInternalError(InternalErrorLoadEvent event); 188 void RecordInternalError(InternalErrorLoadEvent event);
179 PageEndReason EndReasonForPageTransition(ui::PageTransition transition); 189 PageEndReason EndReasonForPageTransition(ui::PageTransition transition);
180 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url); 190 void LogAbortChainSameURLHistogram(int aborted_chain_size_same_url);
181 bool IsNavigationUserInitiated(content::NavigationHandle* handle); 191 bool IsNavigationUserInitiated(content::NavigationHandle* handle);
192 content::RenderFrameHost* GetMainFrame(content::RenderFrameHost* rfh);
182 193
183 // This class tracks a given page load, starting from navigation start / 194 // This class tracks a given page load, starting from navigation start /
184 // provisional load, until a new navigation commits or the navigation fails. 195 // provisional load, until a new navigation commits or the navigation fails.
185 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as 196 // MetricsWebContentsObserver manages a set of provisional PageLoadTrackers, as
186 // well as a committed PageLoadTracker. 197 // well as a committed PageLoadTracker.
187 class PageLoadTracker { 198 class PageLoadTracker {
188 public: 199 public:
189 // Caller must guarantee that the embedder_interface pointer outlives this 200 // Caller must guarantee that the embedder_interface pointer outlives this
190 // class. The PageLoadTracker must not hold on to 201 // class. The PageLoadTracker must not hold on to
191 // currently_committed_load_or_null or navigation_handle beyond the scope of 202 // currently_committed_load_or_null or navigation_handle beyond the scope of
(...skipping 23 matching lines...) Expand all
215 // metrics as the application goes into the background. The application may be 226 // metrics as the application goes into the background. The application may be
216 // killed at any time after this method is invoked without further 227 // killed at any time after this method is invoked without further
217 // notification. 228 // notification.
218 void FlushMetricsOnAppEnterBackground(); 229 void FlushMetricsOnAppEnterBackground();
219 230
220 void NotifyClientRedirectTo(const PageLoadTracker& destination); 231 void NotifyClientRedirectTo(const PageLoadTracker& destination);
221 232
222 void UpdateTiming(const PageLoadTiming& timing, 233 void UpdateTiming(const PageLoadTiming& timing,
223 const PageLoadMetadata& metadata); 234 const PageLoadMetadata& metadata);
224 235
236 void UpdateSubFrameTiming(content::RenderFrameHost* render_frame_host,
237 const PageLoadTiming& new_timing,
238 const PageLoadMetadata& new_metadata);
239
225 // Update metadata for child frames. Updates for child frames arrive 240 // Update metadata for child frames. Updates for child frames arrive
226 // separately from updates for the main frame, so aren't included in 241 // separately from updates for the main frame, so aren't included in
227 // UpdateTiming. 242 // UpdateTiming.
228 void UpdateChildFrameMetadata(const PageLoadMetadata& child_metadata); 243 void UpdateSubFrameMetadata(const PageLoadMetadata& child_metadata);
jkarlin 2017/05/10 16:55:28 Why the rename? Should the comments and argument s
Bryan McQuade 2017/05/10 18:06:15 I wanted to mirror your naming for the subframe co
229 244
230 void OnStartedResource( 245 void OnStartedResource(
231 const ExtraRequestStartInfo& extra_request_started_info); 246 const ExtraRequestStartInfo& extra_request_started_info);
232 247
233 void OnLoadedResource( 248 void OnLoadedResource(
234 const ExtraRequestCompleteInfo& extra_request_complete_info); 249 const ExtraRequestCompleteInfo& extra_request_complete_info);
235 250
236 // Signals that we should stop tracking metrics for the associated page load. 251 // Signals that we should stop tracking metrics for the associated page load.
237 // We may stop tracking a page load if it doesn't meet the criteria for 252 // We may stop tracking a page load if it doesn't meet the criteria for
238 // tracking metrics in DidFinishNavigation. 253 // tracking metrics in DidFinishNavigation.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 const content::WebContentsObserver::MediaPlayerInfo& video_type, 314 const content::WebContentsObserver::MediaPlayerInfo& video_type,
300 bool is_in_main_frame); 315 bool is_in_main_frame);
301 316
302 // Invoked on navigations where a navigation delay was added by the 317 // Invoked on navigations where a navigation delay was added by the
303 // DelayNavigationThrottle. This is a temporary method that will be removed 318 // DelayNavigationThrottle. This is a temporary method that will be removed
304 // once the experiment is complete. 319 // once the experiment is complete.
305 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay, 320 void OnNavigationDelayComplete(base::TimeDelta scheduled_delay,
306 base::TimeDelta actual_delay); 321 base::TimeDelta actual_delay);
307 322
308 private: 323 private:
324 using FrameTreeNodeId = int;
325
309 // This function converts a TimeTicks value taken in the browser process 326 // This function converts a TimeTicks value taken in the browser process
310 // to navigation_start_ if: 327 // to navigation_start_ if:
311 // - base::TimeTicks is not comparable across processes because the clock 328 // - base::TimeTicks is not comparable across processes because the clock
312 // is not system wide monotonic. 329 // is not system wide monotonic.
313 // - *event_time < navigation_start_ 330 // - *event_time < navigation_start_
314 void ClampBrowserTimestampIfInterProcessTimeTickSkew( 331 void ClampBrowserTimestampIfInterProcessTimeTickSkew(
315 base::TimeTicks* event_time); 332 base::TimeTicks* event_time);
316 333
317 void UpdatePageEndInternal(PageEndReason page_end_reason, 334 void UpdatePageEndInternal(PageEndReason page_end_reason,
318 UserInitiatedInfo user_initiated_info, 335 UserInitiatedInfo user_initiated_info,
319 base::TimeTicks timestamp, 336 base::TimeTicks timestamp,
320 bool is_certainly_browser_timestamp); 337 bool is_certainly_browser_timestamp);
321 338
322 // If |final_navigation| is null, then this is an "unparented" abort chain, 339 // If |final_navigation| is null, then this is an "unparented" abort chain,
323 // and represents a sequence of provisional aborts that never ends with a 340 // and represents a sequence of provisional aborts that never ends with a
324 // committed load. 341 // committed load.
325 void LogAbortChainHistograms(content::NavigationHandle* final_navigation); 342 void LogAbortChainHistograms(content::NavigationHandle* final_navigation);
326 343
327 void MaybeUpdateURL(content::NavigationHandle* navigation_handle); 344 void MaybeUpdateURL(content::NavigationHandle* navigation_handle);
328 345
346 // Merge values from |new_paint_timing| into |merged_page_timing_|, offsetting
347 // any new timings by the |navigation_start_offset|.
348 void MergePaintTiming(base::TimeDelta navigation_start_offset,
349 const page_load_metrics::PaintTiming& new_paint_timing,
350 bool is_main_frame);
351
329 UserInputTracker input_tracker_; 352 UserInputTracker input_tracker_;
330 353
331 // Whether we stopped tracking this navigation after it was initiated. We may 354 // Whether we stopped tracking this navigation after it was initiated. We may
332 // stop tracking a navigation if it doesn't meet the criteria for tracking 355 // stop tracking a navigation if it doesn't meet the criteria for tracking
333 // metrics in DidFinishNavigation. 356 // metrics in DidFinishNavigation.
334 bool did_stop_tracking_; 357 bool did_stop_tracking_;
335 358
336 // Whether the application went into the background when this PageLoadTracker 359 // Whether the application went into the background when this PageLoadTracker
337 // was active. This is a temporary boolean for UMA tracking. 360 // was active. This is a temporary boolean for UMA tracking.
338 bool app_entered_background_; 361 bool app_entered_background_;
(...skipping 29 matching lines...) Expand all
368 391
369 base::TimeTicks page_end_time_; 392 base::TimeTicks page_end_time_;
370 393
371 // We record separate metrics for events that occur after a background, 394 // We record separate metrics for events that occur after a background,
372 // because metrics like layout/paint are delayed artificially 395 // because metrics like layout/paint are delayed artificially
373 // when they occur in the background. 396 // when they occur in the background.
374 base::TimeTicks background_time_; 397 base::TimeTicks background_time_;
375 base::TimeTicks foreground_time_; 398 base::TimeTicks foreground_time_;
376 bool started_in_foreground_; 399 bool started_in_foreground_;
377 400
378 PageLoadTiming timing_; 401 // PageLoadTiming for the currently tracked page. The fields in |paint_timing|
402 // are merged across all frames in the document. All other fields are for the
403 // main frame document.
404 PageLoadTiming merged_page_timing_;
405
379 PageLoadMetadata main_frame_metadata_; 406 PageLoadMetadata main_frame_metadata_;
380 PageLoadMetadata child_frame_metadata_; 407 PageLoadMetadata child_frame_metadata_;
381 408
382 ui::PageTransition page_transition_; 409 ui::PageTransition page_transition_;
383 410
384 base::Optional<content::GlobalRequestID> navigation_request_id_; 411 base::Optional<content::GlobalRequestID> navigation_request_id_;
385 412
386 // Whether this page load was user initiated. 413 // Whether this page load was user initiated.
387 UserInitiatedInfo user_initiated_info_; 414 UserInitiatedInfo user_initiated_info_;
388 415
389 // This is a subtle member. If a provisional load A gets aborted by 416 // This is a subtle member. If a provisional load A gets aborted by
390 // provisional load B, which gets aborted by C that eventually commits, then 417 // provisional load B, which gets aborted by C that eventually commits, then
391 // there exists an abort chain of length 2, starting at A's navigation_start. 418 // there exists an abort chain of length 2, starting at A's navigation_start.
392 // This is useful because it allows histograming abort chain lengths based on 419 // This is useful because it allows histograming abort chain lengths based on
393 // what the last load's transition type is. i.e. holding down F-5 to spam 420 // what the last load's transition type is. i.e. holding down F-5 to spam
394 // reload will produce a long chain with the RELOAD transition. 421 // reload will produce a long chain with the RELOAD transition.
395 const int aborted_chain_size_; 422 const int aborted_chain_size_;
396 423
397 // This member counts consecutive provisional aborts that share a url. It will 424 // This member counts consecutive provisional aborts that share a url. It will
398 // always be less than or equal to |aborted_chain_size_|. 425 // always be less than or equal to |aborted_chain_size_|.
399 const int aborted_chain_size_same_url_; 426 const int aborted_chain_size_same_url_;
400 427
401 // Interface to chrome features. Must outlive the class. 428 // Interface to chrome features. Must outlive the class.
402 PageLoadMetricsEmbedderInterface* const embedder_interface_; 429 PageLoadMetricsEmbedderInterface* const embedder_interface_;
403 430
404 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_; 431 std::vector<std::unique_ptr<PageLoadMetricsObserver>> observers_;
405 432
433 // Navigation start offsets for the most recently committed document in each
434 // frame.
435 std::map<FrameTreeNodeId, base::TimeDelta>
436 child_frame_navigation_start_offset_;
437
406 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker); 438 DISALLOW_COPY_AND_ASSIGN(PageLoadTracker);
407 }; 439 };
408 440
409 } // namespace page_load_metrics 441 } // namespace page_load_metrics
410 442
411 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_ 443 #endif // CHROME_BROWSER_PAGE_LOAD_METRICS_PAGE_LOAD_TRACKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698