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

Side by Side Diff: components/page_load_metrics/browser/metrics_web_contents_observer.cc

Issue 1433533007: [page_load_metrics] Get navigation_start from NavigationHandle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@change-names-refactor
Patch Set: navigation_start => NavigationStart Created 5 years, 1 month 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" 5 #include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "components/page_load_metrics/browser/page_load_metrics_macros.h" 10 #include "components/page_load_metrics/browser/page_load_metrics_macros.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 if (!timing.load_event_start.is_zero() && 69 if (!timing.load_event_start.is_zero() &&
70 (timing.dom_content_loaded_event_start.is_zero() || 70 (timing.dom_content_loaded_event_start.is_zero() ||
71 timing.response_start > timing.load_event_start || 71 timing.response_start > timing.load_event_start ||
72 timing.dom_content_loaded_event_start > timing.load_event_start)) { 72 timing.dom_content_loaded_event_start > timing.load_event_start)) {
73 return false; 73 return false;
74 } 74 }
75 75
76 return true; 76 return true;
77 } 77 }
78 78
79 base::Time WallTimeFromTimeTicks(const base::TimeTicks& time) {
80 return base::Time::FromDoubleT(
81 (time - base::TimeTicks::UnixEpoch()).InSecondsF());
82 }
83
84 void RecordInternalError(InternalErrorLoadEvent event) { 79 void RecordInternalError(InternalErrorLoadEvent event) {
85 UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY); 80 UMA_HISTOGRAM_ENUMERATION(kErrorEvents, event, ERR_LAST_ENTRY);
86 } 81 }
87 82
88 base::TimeDelta GetFirstContentfulPaint(const PageLoadTiming& timing) { 83 base::TimeDelta GetFirstContentfulPaint(const PageLoadTiming& timing) {
89 if (timing.first_text_paint.is_zero()) 84 if (timing.first_text_paint.is_zero())
90 return timing.first_image_paint; 85 return timing.first_image_paint;
91 if (timing.first_image_paint.is_zero()) 86 if (timing.first_image_paint.is_zero())
92 return timing.first_text_paint; 87 return timing.first_text_paint;
93 return std::min(timing.first_text_paint, timing.first_image_paint); 88 return std::min(timing.first_text_paint, timing.first_image_paint);
(...skipping 20 matching lines...) Expand all
114 if (seconds < 32) 109 if (seconds < 32)
115 return 4; 110 return 4;
116 return 5; 111 return 5;
117 } 112 }
118 113
119 } // namespace 114 } // namespace
120 115
121 PageLoadTracker::PageLoadTracker( 116 PageLoadTracker::PageLoadTracker(
122 bool in_foreground, 117 bool in_foreground,
123 PageLoadMetricsEmbedderInterface* embedder_interface, 118 PageLoadMetricsEmbedderInterface* embedder_interface,
119 content::NavigationHandle* navigation_handle,
124 base::ObserverList<PageLoadMetricsObserver, true>* observers) 120 base::ObserverList<PageLoadMetricsObserver, true>* observers)
125 : has_commit_(false), 121 : has_commit_(false),
122 navigation_start_(navigation_handle->NavigationStart()),
126 started_in_foreground_(in_foreground), 123 started_in_foreground_(in_foreground),
127 embedder_interface_(embedder_interface), 124 embedder_interface_(embedder_interface),
128 observers_(observers) {} 125 observers_(observers) {}
129 126
130 PageLoadTracker::~PageLoadTracker() { 127 PageLoadTracker::~PageLoadTracker() {
131 if (has_commit_) { 128 if (has_commit_) {
132 RecordTimingHistograms(); 129 RecordTimingHistograms();
133 RecordRappor(); 130 RecordRappor();
134 } 131 }
135 } 132 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 return false; 171 return false;
175 } 172 }
176 173
177 bool PageLoadTracker::HasBackgrounded() { 174 bool PageLoadTracker::HasBackgrounded() {
178 return !started_in_foreground_ || !background_time_.is_null(); 175 return !started_in_foreground_ || !background_time_.is_null();
179 } 176 }
180 177
181 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() { 178 PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() {
182 base::TimeDelta first_background_time; 179 base::TimeDelta first_background_time;
183 base::TimeDelta first_foreground_time; 180 base::TimeDelta first_foreground_time;
184 if (!background_time_.is_null() && started_in_foreground_) { 181 if (!background_time_.is_null() && started_in_foreground_)
185 first_background_time = 182 first_background_time = background_time_ - navigation_start_;
186 WallTimeFromTimeTicks(background_time_) - timing_.navigation_start; 183 if (!foreground_time_.is_null() && !started_in_foreground_)
187 } 184 first_foreground_time = foreground_time_ - navigation_start_;
188 if (!foreground_time_.is_null() && !started_in_foreground_) {
189 first_foreground_time =
190 WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start;
191 }
192 return PageLoadExtraInfo(first_background_time, first_foreground_time, 185 return PageLoadExtraInfo(first_background_time, first_foreground_time,
193 started_in_foreground_); 186 started_in_foreground_);
194 } 187 }
195 188
196 const GURL& PageLoadTracker::GetCommittedURL() { 189 const GURL& PageLoadTracker::GetCommittedURL() {
197 DCHECK(has_commit_); 190 DCHECK(has_commit_);
198 return url_; 191 return url_;
199 } 192 }
200 193
201 // Blink calculates navigation start using TimeTicks, but converts to epoch time 194 // Blink calculates navigation start using TimeTicks, but converts to epoch time
202 // in its public API. Thus, to compare time values to navigation start, we 195 // in its public API. Thus, to compare time values to navigation start, we
203 // calculate the current time since the epoch using TimeTicks, and convert to 196 // calculate the current time since the epoch using TimeTicks, and convert to
204 // Time. This method is similar to how blink converts TimeTicks to epoch time. 197 // Time. This method is similar to how blink converts TimeTicks to epoch time.
205 // There may be slight inaccuracies due to inter-process timestamps, but 198 // There may be slight inaccuracies due to inter-process timestamps, but
206 // this solution is the best we have right now. 199 // this solution is the best we have right now.
207 // 200 //
208 // returns a TimeDelta which is 201 // returns a TimeDelta which is
209 // - Infinity if we were never backgrounded 202 // - Infinity if we were never backgrounded
210 // - null (TimeDelta()) if we started backgrounded 203 // - null (TimeDelta()) if we started backgrounded
211 // - elapsed time to first background if we started in the foreground and 204 // - elapsed time to first background if we started in the foreground and
212 // backgrounded. 205 // backgrounded.
213 base::TimeDelta PageLoadTracker::GetBackgroundDelta() { 206 base::TimeDelta PageLoadTracker::GetBackgroundDelta() {
214 if (started_in_foreground_) { 207 if (started_in_foreground_) {
215 if (background_time_.is_null()) 208 return background_time_.is_null() ? base::TimeDelta::Max()
216 return base::TimeDelta::Max(); 209 : background_time_ - navigation_start_;
217 return WallTimeFromTimeTicks(background_time_) - timing_.navigation_start;
218 } 210 }
219 return base::TimeDelta(); 211 return base::TimeDelta();
220 } 212 }
221 213
222 void PageLoadTracker::RecordTimingHistograms() { 214 void PageLoadTracker::RecordTimingHistograms() {
223 DCHECK(has_commit_); 215 DCHECK(has_commit_);
224 if (timing_.IsEmpty()) { 216 if (timing_.IsEmpty()) {
225 RecordInternalError(ERR_NO_IPCS_RECEIVED); 217 RecordInternalError(ERR_NO_IPCS_RECEIVED);
226 return; 218 return;
227 } 219 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 PAGE_LOAD_HISTOGRAM(kBackgroundHistogramFirstContentfulPaint, 285 PAGE_LOAD_HISTOGRAM(kBackgroundHistogramFirstContentfulPaint,
294 first_contentful_paint); 286 first_contentful_paint);
295 } 287 }
296 } 288 }
297 289
298 // Log time to first foreground / time to first background. Log counts that we 290 // Log time to first foreground / time to first background. Log counts that we
299 // started a relevant page load in the foreground / background. 291 // started a relevant page load in the foreground / background.
300 if (!background_time_.is_null()) { 292 if (!background_time_.is_null()) {
301 PAGE_LOAD_HISTOGRAM(kHistogramFirstBackground, background_delta); 293 PAGE_LOAD_HISTOGRAM(kHistogramFirstBackground, background_delta);
302 } else if (!foreground_time_.is_null()) { 294 } else if (!foreground_time_.is_null()) {
303 PAGE_LOAD_HISTOGRAM( 295 PAGE_LOAD_HISTOGRAM(kHistogramFirstForeground,
304 kHistogramFirstForeground, 296 foreground_time_ - navigation_start_);
305 WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start);
306 } 297 }
307 } 298 }
308 299
309 void PageLoadTracker::RecordProvisionalEvent(ProvisionalLoadEvent event) { 300 void PageLoadTracker::RecordProvisionalEvent(ProvisionalLoadEvent event) {
310 if (HasBackgrounded()) { 301 if (HasBackgrounded()) {
311 UMA_HISTOGRAM_ENUMERATION(kBackgroundProvisionalEvents, event, 302 UMA_HISTOGRAM_ENUMERATION(kBackgroundProvisionalEvents, event,
312 PROVISIONAL_LOAD_LAST_ENTRY); 303 PROVISIONAL_LOAD_LAST_ENTRY);
313 } else { 304 } else {
314 UMA_HISTOGRAM_ENUMERATION(kProvisionalEvents, event, 305 UMA_HISTOGRAM_ENUMERATION(kProvisionalEvents, event,
315 PROVISIONAL_LOAD_LAST_ENTRY); 306 PROVISIONAL_LOAD_LAST_ENTRY);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 return; 405 return;
415 if (embedder_interface_->IsPrerendering(web_contents())) 406 if (embedder_interface_->IsPrerendering(web_contents()))
416 return; 407 return;
417 // We can have two provisional loads in some cases. E.g. a same-site 408 // We can have two provisional loads in some cases. E.g. a same-site
418 // navigation can have a concurrent cross-process navigation started 409 // navigation can have a concurrent cross-process navigation started
419 // from the omnibox. 410 // from the omnibox.
420 DCHECK_GT(2ul, provisional_loads_.size()); 411 DCHECK_GT(2ul, provisional_loads_.size());
421 // Passing raw pointers to observers_ and embedder_interface_ is safe because 412 // Passing raw pointers to observers_ and embedder_interface_ is safe because
422 // the MetricsWebContentsObserver owns them both list and they are torn down 413 // the MetricsWebContentsObserver owns them both list and they are torn down
423 // after the PageLoadTracker. 414 // after the PageLoadTracker.
424 provisional_loads_.insert( 415 provisional_loads_.insert(navigation_handle,
425 navigation_handle, 416 make_scoped_ptr(new PageLoadTracker(
426 make_scoped_ptr(new PageLoadTracker( 417 in_foreground_, embedder_interface_.get(),
427 in_foreground_, embedder_interface_.get(), &observers_))); 418 navigation_handle, &observers_)));
428 } 419 }
429 420
430 void MetricsWebContentsObserver::DidFinishNavigation( 421 void MetricsWebContentsObserver::DidFinishNavigation(
431 content::NavigationHandle* navigation_handle) { 422 content::NavigationHandle* navigation_handle) {
432 if (!navigation_handle->IsInMainFrame()) 423 if (!navigation_handle->IsInMainFrame())
433 return; 424 return;
434 425
435 scoped_ptr<PageLoadTracker> finished_nav( 426 scoped_ptr<PageLoadTracker> finished_nav(
436 provisional_loads_.take_and_erase(navigation_handle)); 427 provisional_loads_.take_and_erase(navigation_handle));
437 // There's a chance a navigation could have started before we were added to a 428 // There's a chance a navigation could have started before we were added to a
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 517
527 if (!committed_load_->UpdateTiming(timing)) { 518 if (!committed_load_->UpdateTiming(timing)) {
528 // If the page load tracker cannot update its timing, something is wrong 519 // If the page load tracker cannot update its timing, something is wrong
529 // with the IPC (it's from another load, or it's invalid in some other way). 520 // with the IPC (it's from another load, or it's invalid in some other way).
530 // We expect this to be a rare occurrence. 521 // We expect this to be a rare occurrence.
531 RecordInternalError(ERR_BAD_TIMING_IPC); 522 RecordInternalError(ERR_BAD_TIMING_IPC);
532 } 523 }
533 } 524 }
534 525
535 } // namespace page_load_metrics 526 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698