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

Side by Side Diff: chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc

Issue 2152683004: Refactor PageLoadMetricsObserver completion callback policy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@relevantloads
Patch Set: remove histogram checks that can be flaky due to immediate logging Created 4 years, 5 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 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 "chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_ observer.h" 5 #include "chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_ observer.h"
6 #include <string> 6 #include <string>
7 7
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "components/page_load_metrics/browser/page_load_metrics_util.h" 10 #include "components/page_load_metrics/browser/page_load_metrics_util.h"
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 385
386 void FromGWSPageLoadMetricsLogger::SetPreviouslyCommittedUrl(const GURL& url) { 386 void FromGWSPageLoadMetricsLogger::SetPreviouslyCommittedUrl(const GURL& url) {
387 previously_committed_url_is_search_results_ = IsGoogleSearchResultUrl(url); 387 previously_committed_url_is_search_results_ = IsGoogleSearchResultUrl(url);
388 previously_committed_url_is_search_redirector_ = 388 previously_committed_url_is_search_redirector_ =
389 IsGoogleSearchRedirectorUrl(url); 389 IsGoogleSearchRedirectorUrl(url);
390 } 390 }
391 391
392 void FromGWSPageLoadMetricsLogger::SetProvisionalUrl(const GURL& url) { 392 void FromGWSPageLoadMetricsLogger::SetProvisionalUrl(const GURL& url) {
393 provisional_url_has_search_hostname_ = 393 provisional_url_has_search_hostname_ =
394 IsGoogleSearchHostname(url.host_piece()); 394 IsGoogleSearchHostname(url.host_piece());
395 provisional_url_is_non_http_or_https_ = !url.SchemeIsHTTPOrHTTPS();
396 } 395 }
397 396
398 FromGWSPageLoadMetricsObserver::FromGWSPageLoadMetricsObserver() {} 397 FromGWSPageLoadMetricsObserver::FromGWSPageLoadMetricsObserver() {}
399 398
400 void FromGWSPageLoadMetricsObserver::OnStart( 399 void FromGWSPageLoadMetricsObserver::OnStart(
401 content::NavigationHandle* navigation_handle, 400 content::NavigationHandle* navigation_handle,
402 const GURL& currently_committed_url, 401 const GURL& currently_committed_url,
403 bool started_in_foreground) { 402 bool started_in_foreground) {
404 logger_.SetPreviouslyCommittedUrl(currently_committed_url); 403 logger_.SetPreviouslyCommittedUrl(currently_committed_url);
405 logger_.SetProvisionalUrl(navigation_handle->GetURL()); 404 logger_.SetProvisionalUrl(navigation_handle->GetURL());
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 const page_load_metrics::PageLoadExtraInfo& extra_info) { 468 const page_load_metrics::PageLoadExtraInfo& extra_info) {
470 logger_.OnParseStop(timing, extra_info); 469 logger_.OnParseStop(timing, extra_info);
471 } 470 }
472 471
473 void FromGWSPageLoadMetricsObserver::OnComplete( 472 void FromGWSPageLoadMetricsObserver::OnComplete(
474 const page_load_metrics::PageLoadTiming& timing, 473 const page_load_metrics::PageLoadTiming& timing,
475 const page_load_metrics::PageLoadExtraInfo& extra_info) { 474 const page_load_metrics::PageLoadExtraInfo& extra_info) {
476 logger_.OnComplete(timing, extra_info); 475 logger_.OnComplete(timing, extra_info);
477 } 476 }
478 477
478 void FromGWSPageLoadMetricsObserver::OnFailedProvisionalLoad(
479 const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info,
480 const page_load_metrics::PageLoadExtraInfo& extra_info) {
481 logger_.OnFailedProvisionalLoad(failed_load_info, extra_info);
482 }
483
479 void FromGWSPageLoadMetricsObserver::OnUserInput( 484 void FromGWSPageLoadMetricsObserver::OnUserInput(
480 const blink::WebInputEvent& event) { 485 const blink::WebInputEvent& event) {
481 logger_.OnUserInput(event); 486 logger_.OnUserInput(event);
482 } 487 }
483 488
484 void FromGWSPageLoadMetricsLogger::OnComplete( 489 void FromGWSPageLoadMetricsLogger::OnComplete(
485 const page_load_metrics::PageLoadTiming& timing, 490 const page_load_metrics::PageLoadTiming& timing,
486 const page_load_metrics::PageLoadExtraInfo& extra_info) { 491 const page_load_metrics::PageLoadExtraInfo& extra_info) {
487 if (!ShouldLogMetrics(extra_info.committed_url)) 492 if (!ShouldLogPostCommitMetrics(extra_info.committed_url))
488 return; 493 return;
489 494
490 // If we have a committed load but |timing.IsEmpty()|, then this load was not
491 // tracked by the renderer. In this case, it is not possible to know whether
492 // the abort signals came before the page painted. Additionally, for
493 // consistency with core PageLoad metrics, we ignore non-render-tracked
494 // loads when tracking aborts after commit.
495 UserAbortType abort_type = extra_info.abort_type; 495 UserAbortType abort_type = extra_info.abort_type;
496 if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info)) 496 if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info))
497 return; 497 return;
498 498
499 base::TimeDelta time_to_abort = extra_info.time_to_abort.value(); 499 // If we did not receive any timing IPCs from the render process, we can't
500 if (extra_info.committed_url.is_empty()) { 500 // know for certain if the page was truly aborted before paint, or if the
501 LogProvisionalAborts(abort_type, time_to_abort); 501 // abort happened before we received the IPC from the render process. Thus, we
502 return; 502 // do not log aborts for these page loads. Tracked page loads that receive no
503 } 503 // timing IPCs are tracked via the ERR_NO_IPCS_RECEIVED error code in the
504 504 // PageLoad.Events.InternalError histogram, so we can keep track of how often
505 // If we didn't receive any timing data but did commit, this is likely not a 505 // this happens.
506 // renderer-tracked navigation, so ignore it.
507 if (timing.IsEmpty()) 506 if (timing.IsEmpty())
508 return; 507 return;
509 508
509 base::TimeDelta time_to_abort = extra_info.time_to_abort.value();
510 if (!timing.first_paint || timing.first_paint >= time_to_abort) { 510 if (!timing.first_paint || timing.first_paint >= time_to_abort) {
511 LogCommittedAbortsBeforePaint(abort_type, time_to_abort); 511 LogCommittedAbortsBeforePaint(abort_type, time_to_abort);
512 } else if (WasAbortedBeforeInteraction(abort_type, 512 } else if (WasAbortedBeforeInteraction(abort_type,
513 first_user_interaction_after_paint_, 513 first_user_interaction_after_paint_,
514 extra_info.time_to_abort)) { 514 extra_info.time_to_abort)) {
515 LogAbortsAfterPaintBeforeInteraction(abort_type, time_to_abort); 515 LogAbortsAfterPaintBeforeInteraction(abort_type, time_to_abort);
516 } 516 }
517 } 517 }
518 518
519 bool FromGWSPageLoadMetricsLogger::ShouldLogMetrics(const GURL& committed_url) { 519 void FromGWSPageLoadMetricsLogger::OnFailedProvisionalLoad(
520 const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info,
521 const page_load_metrics::PageLoadExtraInfo& extra_info) {
522 if (!ShouldLogFailedProvisionalLoadMetrics())
523 return;
524
525 UserAbortType abort_type = extra_info.abort_type;
526 if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info))
527 return;
528
529 LogProvisionalAborts(abort_type, extra_info.time_to_abort.value());
530 }
531
532 bool FromGWSPageLoadMetricsLogger::ShouldLogFailedProvisionalLoadMetrics() {
533 // See comment in ShouldLogPostCommitMetrics above the call to
534 // IsGoogleSearchHostname for more info on this if test.
535 if (provisional_url_has_search_hostname_)
536 return false;
537
538 return previously_committed_url_is_search_results_ ||
539 previously_committed_url_is_search_redirector_;
540 }
541
542 bool FromGWSPageLoadMetricsLogger::ShouldLogPostCommitMetrics(
543 const GURL& committed_url) {
544 DCHECK(!committed_url.is_empty());
545
520 // If this page has a URL on a known google search hostname, then it may be a 546 // If this page has a URL on a known google search hostname, then it may be a
521 // page associated with search (either a search results page, or a search 547 // page associated with search (either a search results page, or a search
522 // redirector url), so we should not log stats. We could try to detect only 548 // redirector url), so we should not log stats. We could try to detect only
523 // the specific known search URLs here, and log navigations to other pages on 549 // the specific known search URLs here, and log navigations to other pages on
524 // the google search hostname (for example, a search for 'about google' 550 // the google search hostname (for example, a search for 'about google'
525 // includes a result for https://www.google.com/about/), however, we assume 551 // includes a result for https://www.google.com/about/), however, we assume
526 // these cases are relatively uncommon, and we run the risk of logging metrics 552 // these cases are relatively uncommon, and we run the risk of logging metrics
527 // for some search redirector URLs. Thus we choose the more conservative 553 // for some search redirector URLs. Thus we choose the more conservative
528 // approach of ignoring all urls on known search hostnames. We use the 554 // approach of ignoring all urls on known search hostnames.
529 // provisional url if the navigation didn't commit. Also ignore navigations to 555 if (IsGoogleSearchHostname(committed_url.host_piece()))
530 // other URL schemes, such as app navigations via intent://. 556 return false;
531 if (committed_url.is_empty()) {
532 if (provisional_url_has_search_hostname_ ||
533 provisional_url_is_non_http_or_https_)
534 return false;
535 } else {
536 if (IsGoogleSearchHostname(committed_url.host_piece()) ||
537 !committed_url.SchemeIsHTTPOrHTTPS())
538 return false;
539 }
540 557
541 // We're only interested in tracking navigations (e.g. clicks) initiated via 558 // We're only interested in tracking navigations (e.g. clicks) initiated via
542 // links. Note that the redirector will mask these, so don't enforce this if 559 // links. Note that the redirector will mask these, so don't enforce this if
543 // the navigation came from a redirect url. TODO(csharrison): Use this signal 560 // the navigation came from a redirect url. TODO(csharrison): Use this signal
544 // for provisional loads when the content APIs allow for it. 561 // for provisional loads when the content APIs allow for it.
545 if (previously_committed_url_is_search_results_ && 562 if (previously_committed_url_is_search_results_ &&
546 (committed_url.is_empty() || navigation_initiated_via_link_)) { 563 navigation_initiated_via_link_) {
547 return true; 564 return true;
548 } 565 }
549 566
550 // If the navigation was via the search redirector, then the information about 567 // If the navigation was via the search redirector, then the information about
551 // whether the navigation was from a link would have been associated with the 568 // whether the navigation was from a link would have been associated with the
552 // navigation to the redirector, and not included in the redirected 569 // navigation to the redirector, and not included in the redirected
553 // navigation. Therefore, do not require link navigation this case. 570 // navigation. Therefore, do not require link navigation this case.
554 return previously_committed_url_is_search_redirector_; 571 return previously_committed_url_is_search_redirector_;
555 } 572 }
556 573
557 bool FromGWSPageLoadMetricsLogger::ShouldLogForegroundEventAfterCommit( 574 bool FromGWSPageLoadMetricsLogger::ShouldLogForegroundEventAfterCommit(
558 const base::Optional<base::TimeDelta>& event, 575 const base::Optional<base::TimeDelta>& event,
559 const page_load_metrics::PageLoadExtraInfo& info) { 576 const page_load_metrics::PageLoadExtraInfo& info) {
560 DCHECK(!info.committed_url.is_empty()) 577 DCHECK(!info.committed_url.is_empty())
561 << "ShouldLogForegroundEventAfterCommit called without committed URL."; 578 << "ShouldLogForegroundEventAfterCommit called without committed URL.";
562 return ShouldLogMetrics(info.committed_url) && 579 return ShouldLogPostCommitMetrics(info.committed_url) &&
563 WasStartedInForegroundOptionalEventInForeground(event, info); 580 WasStartedInForegroundOptionalEventInForeground(event, info);
564 } 581 }
565 582
566 void FromGWSPageLoadMetricsLogger::OnDomContentLoadedEventStart( 583 void FromGWSPageLoadMetricsLogger::OnDomContentLoadedEventStart(
567 const page_load_metrics::PageLoadTiming& timing, 584 const page_load_metrics::PageLoadTiming& timing,
568 const page_load_metrics::PageLoadExtraInfo& extra_info) { 585 const page_load_metrics::PageLoadExtraInfo& extra_info) {
569 if (ShouldLogForegroundEventAfterCommit(timing.dom_content_loaded_event_start, 586 if (ShouldLogForegroundEventAfterCommit(timing.dom_content_loaded_event_start,
570 extra_info)) { 587 extra_info)) {
571 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSDomContentLoaded, 588 PAGE_LOAD_HISTOGRAM(internal::kHistogramFromGWSDomContentLoaded,
572 timing.dom_content_loaded_event_start.value()); 589 timing.dom_content_loaded_event_start.value());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 } 667 }
651 668
652 void FromGWSPageLoadMetricsLogger::OnUserInput( 669 void FromGWSPageLoadMetricsLogger::OnUserInput(
653 const blink::WebInputEvent& event) { 670 const blink::WebInputEvent& event) {
654 if (first_paint_triggered_ && !first_user_interaction_after_paint_) { 671 if (first_paint_triggered_ && !first_user_interaction_after_paint_) {
655 DCHECK(!navigation_start_.is_null()); 672 DCHECK(!navigation_start_.is_null());
656 first_user_interaction_after_paint_ = 673 first_user_interaction_after_paint_ =
657 base::TimeTicks::Now() - navigation_start_; 674 base::TimeTicks::Now() - navigation_start_;
658 } 675 }
659 } 676 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698