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

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

Issue 2859393002: Report page load timing information for child frames. (Closed)
Patch Set: add browsertests 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 #include "chrome/browser/page_load_metrics/page_load_tracker.h" 5 #include "chrome/browser/page_load_metrics/page_load_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <ostream> 8 #include <ostream>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h" 15 #include "chrome/browser/page_load_metrics/page_load_metrics_embedder_interface. h"
16 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h" 16 #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
17 #include "chrome/browser/prerender/prerender_contents.h" 17 #include "chrome/browser/prerender/prerender_contents.h"
18 #include "chrome/common/page_load_metrics/page_load_timing.h" 18 #include "chrome/common/page_load_metrics/page_load_timing.h"
19 #include "content/public/browser/navigation_details.h" 19 #include "content/public/browser/navigation_details.h"
20 #include "content/public/browser/navigation_handle.h" 20 #include "content/public/browser/navigation_handle.h"
21 #include "content/public/browser/render_frame_host.h"
21 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
22 #include "content/public/browser/web_contents_observer.h" 23 #include "content/public/browser/web_contents_observer.h"
23 #include "content/public/common/browser_side_navigation_policy.h" 24 #include "content/public/common/browser_side_navigation_policy.h"
24 #include "ui/base/page_transition_types.h" 25 #include "ui/base/page_transition_types.h"
25 26
26 // This macro invokes the specified method on each observer, passing the 27 // This macro invokes the specified method on each observer, passing the
27 // variable length arguments as the method's arguments, and removes the observer 28 // variable length arguments as the method's arguments, and removes the observer
28 // from the list of observers if the given method returns STOP_OBSERVING. 29 // from the list of observers if the given method returns STOP_OBSERVING.
29 #define INVOKE_AND_PRUNE_OBSERVERS(observers, Method, ...) \ 30 #define INVOKE_AND_PRUNE_OBSERVERS(observers, Method, ...) \
30 for (auto it = observers.begin(); it != observers.end();) { \ 31 for (auto it = observers.begin(); it != observers.end();) { \
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 navigation_handle->GetWebContents()->GetContentsMimeType()); 505 navigation_handle->GetWebContents()->GetContentsMimeType());
505 506
506 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle); 507 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnCommit, navigation_handle);
507 LogAbortChainHistograms(navigation_handle); 508 LogAbortChainHistograms(navigation_handle);
508 } 509 }
509 510
510 void PageLoadTracker::DidFinishSubFrameNavigation( 511 void PageLoadTracker::DidFinishSubFrameNavigation(
511 content::NavigationHandle* navigation_handle) { 512 content::NavigationHandle* navigation_handle) {
512 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnDidFinishSubFrameNavigation, 513 INVOKE_AND_PRUNE_OBSERVERS(observers_, OnDidFinishSubFrameNavigation,
513 navigation_handle); 514 navigation_handle);
515
516 // todo we don't want to erase if it's an aborted load (prev doc remains
517 // committed in that case)
518 child_frame_navigation_start_.erase(navigation_handle->GetFrameTreeNodeId());
519 if (navigation_handle->HasCommitted() &&
jkarlin 2017/05/05 19:19:25 Note that error pages count as commits.
Bryan McQuade 2017/05/07 19:32:11 good catch, thanks!. I decided that for tracking t
520 !navigation_handle->IsSameDocument()) {
521 DCHECK_GE(navigation_handle->NavigationStart(), navigation_start_);
522 base::TimeDelta navigation_delta =
523 navigation_handle->NavigationStart() - navigation_start_;
524 child_frame_navigation_start_.insert(std::make_pair(
525 navigation_handle->GetFrameTreeNodeId(), navigation_delta));
526 }
514 } 527 }
515 528
516 void PageLoadTracker::FailedProvisionalLoad( 529 void PageLoadTracker::FailedProvisionalLoad(
517 content::NavigationHandle* navigation_handle, 530 content::NavigationHandle* navigation_handle,
518 base::TimeTicks failed_load_time) { 531 base::TimeTicks failed_load_time) {
519 DCHECK(!failed_provisional_load_info_); 532 DCHECK(!failed_provisional_load_info_);
520 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo( 533 failed_provisional_load_info_.reset(new FailedProvisionalLoadInfo(
521 failed_load_time - navigation_handle->NavigationStart(), 534 failed_load_time - navigation_handle->NavigationStart(),
522 navigation_handle->GetNetErrorCode())); 535 navigation_handle->GetNetErrorCode()));
523 } 536 }
(...skipping 30 matching lines...) Expand all
554 if (destination.navigation_start() > first_paint_time) 567 if (destination.navigation_start() > first_paint_time)
555 first_paint_to_navigation = 568 first_paint_to_navigation =
556 destination.navigation_start() - first_paint_time; 569 destination.navigation_start() - first_paint_time;
557 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation, 570 PAGE_LOAD_HISTOGRAM(internal::kClientRedirectFirstPaintToNavigation,
558 first_paint_to_navigation); 571 first_paint_to_navigation);
559 } else { 572 } else {
560 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true); 573 UMA_HISTOGRAM_BOOLEAN(internal::kClientRedirectWithoutPaint, true);
561 } 574 }
562 } 575 }
563 576
564 void PageLoadTracker::UpdateChildFrameMetadata( 577 void PageLoadTracker::UpdateSubFrameTiming(
578 content::RenderFrameHost* render_frame_host,
579 const PageLoadTiming& new_timing,
580 const PageLoadMetadata& new_metadata) {
581 UpdateSubFrameMetadata(new_metadata);
582 const auto it = child_frame_navigation_start_.find(
583 render_frame_host->GetFrameTreeNodeId());
584 if (it == child_frame_navigation_start_.end()) {
585 // note that this can happen if a navigation starts but aborts and then the
586 // frame contents is updated via e.g. document.open/document.write from its
587 // parent. we probably want this to pass through to observers, but it's
jkarlin 2017/05/05 19:19:25 This can also happen if a navigation aborts and fa
Bryan McQuade 2017/05/07 19:32:10 Yes - I fixed our tracking of loads in DidFinishSu
588 // unclear what we should use for a nav start value (what is the nav start
589 // value in the render process? maybe we should be sending the nav start
590 // timeticks from the renderer?)
591 // todo log an error here to keep track of frequency of this case
592 return;
593 }
594 const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
595 for (const auto& observer : observers_) {
596 observer->OnSubFrameTimingUpdate(render_frame_host->GetFrameTreeNodeId(),
597 it->second, new_timing, new_metadata,
598 info);
599 }
600 }
601
602 void PageLoadTracker::UpdateSubFrameMetadata(
565 const PageLoadMetadata& child_metadata) { 603 const PageLoadMetadata& child_metadata) {
566 // Merge the child loading behavior flags with any we've already observed, 604 // Merge the child loading behavior flags with any we've already observed,
567 // possibly from other child frames. 605 // possibly from other child frames.
568 const int last_child_loading_behavior_flags = 606 const int last_child_loading_behavior_flags =
569 child_frame_metadata_.behavior_flags; 607 child_frame_metadata_.behavior_flags;
570 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags; 608 child_frame_metadata_.behavior_flags |= child_metadata.behavior_flags;
571 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags) 609 if (last_child_loading_behavior_flags == child_frame_metadata_.behavior_flags)
572 return; 610 return;
573 611
574 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo()); 612 PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo());
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 observer->MediaStartedPlaying(video_type, is_in_main_frame); 850 observer->MediaStartedPlaying(video_type, is_in_main_frame);
813 } 851 }
814 852
815 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay, 853 void PageLoadTracker::OnNavigationDelayComplete(base::TimeDelta scheduled_delay,
816 base::TimeDelta actual_delay) { 854 base::TimeDelta actual_delay) {
817 for (const auto& observer : observers_) 855 for (const auto& observer : observers_)
818 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay); 856 observer->OnNavigationDelayComplete(scheduled_delay, actual_delay);
819 } 857 }
820 858
821 } // namespace page_load_metrics 859 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698