OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |