Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "components/page_load_metrics/common/page_load_metrics_messages.h" | 9 #include "components/page_load_metrics/common/page_load_metrics_messages.h" |
| 10 #include "components/page_load_metrics/common/page_load_timing.h" | 10 #include "components/page_load_metrics/common/page_load_timing.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 #include "content/public/browser/navigation_details.h" | 12 #include "content/public/browser/navigation_details.h" |
| 13 #include "content/public/browser/navigation_handle.h" | 13 #include "content/public/browser/navigation_handle.h" |
| 14 #include "content/public/browser/render_frame_host.h" | 14 #include "content/public/browser/render_frame_host.h" |
| 15 #include "content/public/browser/web_contents.h" | 15 #include "content/public/browser/web_contents.h" |
| 16 #include "content/public/browser/web_contents_observer.h" | 16 #include "content/public/browser/web_contents_observer.h" |
| 17 #include "content/public/browser/web_contents_user_data.h" | 17 #include "content/public/browser/web_contents_user_data.h" |
| 18 #include "ipc/ipc_message.h" | 18 #include "ipc/ipc_message.h" |
| 19 #include "ipc/ipc_message_macros.h" | 19 #include "ipc/ipc_message_macros.h" |
| 20 #include "net/base/swr_histogram_domains/swr_histogram_domains.h" | |
| 21 #include "url/gurl.h" | |
| 20 | 22 |
| 21 DEFINE_WEB_CONTENTS_USER_DATA_KEY( | 23 DEFINE_WEB_CONTENTS_USER_DATA_KEY( |
| 22 page_load_metrics::MetricsWebContentsObserver); | 24 page_load_metrics::MetricsWebContentsObserver); |
| 23 | 25 |
| 24 namespace page_load_metrics { | 26 namespace page_load_metrics { |
| 25 | 27 |
| 26 namespace { | 28 namespace { |
| 27 | 29 |
| 28 bool IsValidPageLoadTiming(const PageLoadTiming& timing) { | 30 bool IsValidPageLoadTiming(const PageLoadTiming& timing) { |
| 29 if (timing.IsEmpty()) | 31 if (timing.IsEmpty()) |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 57 } | 59 } |
| 58 | 60 |
| 59 } // namespace | 61 } // namespace |
| 60 | 62 |
| 61 #define PAGE_LOAD_HISTOGRAM(name, sample) \ | 63 #define PAGE_LOAD_HISTOGRAM(name, sample) \ |
| 62 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ | 64 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ |
| 63 base::TimeDelta::FromMilliseconds(10), \ | 65 base::TimeDelta::FromMilliseconds(10), \ |
| 64 base::TimeDelta::FromMinutes(10), 100) | 66 base::TimeDelta::FromMinutes(10), 100) |
| 65 | 67 |
| 66 PageLoadTracker::PageLoadTracker(bool in_foreground) | 68 PageLoadTracker::PageLoadTracker(bool in_foreground) |
| 67 : has_commit_(false), started_in_foreground_(in_foreground) { | 69 : has_commit_(false), |
| 70 started_in_foreground_(in_foreground), | |
| 71 include_in_stale_while_revalidate_experiment_(false) { | |
| 68 RecordEvent(PAGE_LOAD_STARTED); | 72 RecordEvent(PAGE_LOAD_STARTED); |
| 69 } | 73 } |
| 70 | 74 |
| 71 PageLoadTracker::~PageLoadTracker() { | 75 PageLoadTracker::~PageLoadTracker() { |
| 72 // Even a load that failed a provisional load should log | 76 // Even a load that failed a provisional load should log |
| 73 // that it aborted before first layout. | 77 // that it aborted before first layout. |
| 74 if (timing_.first_layout.is_zero()) | 78 if (timing_.first_layout.is_zero()) |
| 75 RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); | 79 RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); |
| 76 | 80 |
| 77 if (has_commit_) | 81 if (has_commit_) |
| 78 RecordTimingHistograms(); | 82 RecordTimingHistograms(); |
| 79 } | 83 } |
| 80 | 84 |
| 81 void PageLoadTracker::WebContentsHidden() { | 85 void PageLoadTracker::WebContentsHidden() { |
| 82 // Only log the first time we background in a given page load. | 86 // Only log the first time we background in a given page load. |
| 83 if (background_time_.is_null()) { | 87 if (background_time_.is_null()) { |
| 84 background_time_ = base::TimeTicks::Now(); | 88 background_time_ = base::TimeTicks::Now(); |
| 85 } | 89 } |
| 86 } | 90 } |
| 87 | 91 |
| 88 void PageLoadTracker::Commit() { | 92 void PageLoadTracker::Commit() { |
| 89 has_commit_ = true; | 93 has_commit_ = true; |
| 90 } | 94 } |
| 91 | 95 |
| 96 void PageLoadTracker::IncludeInStaleWhileRevalidateExperiment() { | |
| 97 include_in_stale_while_revalidate_experiment_ = true; | |
| 98 } | |
| 99 | |
| 92 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& timing) { | 100 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& timing) { |
| 93 // Throw away IPCs that are not relevant to the current navigation. | 101 // Throw away IPCs that are not relevant to the current navigation. |
| 94 if (!timing_.navigation_start.is_null() && | 102 if (!timing_.navigation_start.is_null() && |
| 95 timing_.navigation_start != timing.navigation_start) { | 103 timing_.navigation_start != timing.navigation_start) { |
| 96 // TODO(csharrison) uma log a counter here | 104 // TODO(csharrison) uma log a counter here |
| 97 return false; | 105 return false; |
| 98 } | 106 } |
| 99 if (IsValidPageLoadTiming(timing)) { | 107 if (IsValidPageLoadTiming(timing)) { |
| 100 timing_ = timing; | 108 timing_ = timing; |
| 101 return true; | 109 return true; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 127 } | 135 } |
| 128 } | 136 } |
| 129 if (!timing_.load_event_start.is_zero()) { | 137 if (!timing_.load_event_start.is_zero()) { |
| 130 if (timing_.load_event_start < background_delta) { | 138 if (timing_.load_event_start < background_delta) { |
| 131 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired", | 139 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired", |
| 132 timing_.load_event_start); | 140 timing_.load_event_start); |
| 133 } else { | 141 } else { |
| 134 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", | 142 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", |
| 135 timing_.load_event_start); | 143 timing_.load_event_start); |
| 136 } | 144 } |
| 145 if (include_in_stale_while_revalidate_experiment_) { | |
| 146 PAGE_LOAD_HISTOGRAM( | |
| 147 "PageLoad.Timing2.NavigationToLoadEventFired_" | |
| 148 "StaleWhileRevalidateExperiment", | |
| 149 timing_.load_event_start); | |
| 150 } | |
| 137 } | 151 } |
| 138 if (!timing_.first_layout.is_zero()) { | 152 if (!timing_.first_layout.is_zero()) { |
| 139 if (timing_.first_layout < background_delta) { | 153 if (timing_.first_layout < background_delta) { |
| 140 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", | 154 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", |
| 141 timing_.first_layout); | 155 timing_.first_layout); |
| 142 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); | 156 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); |
| 143 } else { | 157 } else { |
| 144 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", | 158 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", |
| 145 timing_.first_layout); | 159 timing_.first_layout); |
| 146 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); | 160 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); |
| 147 } | 161 } |
| 162 if (include_in_stale_while_revalidate_experiment_) { | |
| 163 PAGE_LOAD_HISTOGRAM( | |
| 164 "PageLoad.Timing2.NavigationToFirstLayout_" | |
| 165 "StaleWhileRevalidateExperiment", | |
| 166 timing_.first_layout); | |
| 167 } | |
| 148 } | 168 } |
| 149 if (!timing_.first_text_paint.is_zero()) { | 169 if (!timing_.first_text_paint.is_zero()) { |
| 150 if (timing_.first_text_paint < background_delta) { | 170 if (timing_.first_text_paint < background_delta) { |
| 151 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstTextPaint", | 171 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstTextPaint", |
| 152 timing_.first_text_paint); | 172 timing_.first_text_paint); |
| 173 | |
|
tyoshino (SeeGerritForStatus)
2015/10/19 07:15:10
inserted accidentally?
Adam Rice
2015/10/19 12:03:07
Yes. Fixed.
| |
| 153 } else { | 174 } else { |
| 154 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstTextPaint.BG", | 175 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstTextPaint.BG", |
| 155 timing_.first_text_paint); | 176 timing_.first_text_paint); |
| 156 } | 177 } |
| 178 if (include_in_stale_while_revalidate_experiment_) { | |
| 179 PAGE_LOAD_HISTOGRAM( | |
| 180 "PageLoad.Timing2.NavigationToFirstTextPaint_" | |
| 181 "StaleWhileRevalidateExperiment", | |
| 182 timing_.first_text_paint); | |
| 183 } | |
| 157 } | 184 } |
| 158 } | 185 } |
| 159 | 186 |
| 160 void PageLoadTracker::RecordEvent(PageLoadEvent event) { | 187 void PageLoadTracker::RecordEvent(PageLoadEvent event) { |
| 161 UMA_HISTOGRAM_ENUMERATION( | 188 UMA_HISTOGRAM_ENUMERATION( |
| 162 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); | 189 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); |
| 163 } | 190 } |
| 164 | 191 |
| 165 MetricsWebContentsObserver::MetricsWebContentsObserver( | 192 MetricsWebContentsObserver::MetricsWebContentsObserver( |
| 166 content::WebContents* web_contents) | 193 content::WebContents* web_contents) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 if (navigation_handle->IsSamePage()) | 242 if (navigation_handle->IsSamePage()) |
| 216 return; | 243 return; |
| 217 | 244 |
| 218 // Eagerly log the previous UMA even if we don't care about the current | 245 // Eagerly log the previous UMA even if we don't care about the current |
| 219 // navigation. | 246 // navigation. |
| 220 committed_load_.reset(); | 247 committed_load_.reset(); |
| 221 | 248 |
| 222 if (!IsRelevantNavigation(navigation_handle)) | 249 if (!IsRelevantNavigation(navigation_handle)) |
| 223 return; | 250 return; |
| 224 | 251 |
| 252 if (net::swr_histogram_domains::IsHostInSWRHistogramDomain( | |
| 253 navigation_handle->GetURL().host())) { | |
| 254 finished_nav->IncludeInStaleWhileRevalidateExperiment(); | |
| 255 } | |
| 256 | |
| 225 committed_load_ = finished_nav.Pass(); | 257 committed_load_ = finished_nav.Pass(); |
| 226 committed_load_->Commit(); | 258 committed_load_->Commit(); |
| 227 } | 259 } |
| 228 | 260 |
| 229 void MetricsWebContentsObserver::WasShown() { | 261 void MetricsWebContentsObserver::WasShown() { |
| 230 in_foreground_ = true; | 262 in_foreground_ = true; |
| 231 } | 263 } |
| 232 | 264 |
| 233 void MetricsWebContentsObserver::WasHidden() { | 265 void MetricsWebContentsObserver::WasHidden() { |
| 234 in_foreground_ = false; | 266 in_foreground_ = false; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 // sure here that we aren't logging UMA for internal pages. | 306 // sure here that we aren't logging UMA for internal pages. |
| 275 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | 307 const GURL& browser_url = web_contents()->GetLastCommittedURL(); |
| 276 return navigation_handle->IsInMainFrame() && | 308 return navigation_handle->IsInMainFrame() && |
| 277 !navigation_handle->IsSamePage() && | 309 !navigation_handle->IsSamePage() && |
| 278 !navigation_handle->IsErrorPage() && | 310 !navigation_handle->IsErrorPage() && |
| 279 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && | 311 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && |
| 280 browser_url.SchemeIsHTTPOrHTTPS(); | 312 browser_url.SchemeIsHTTPOrHTTPS(); |
| 281 } | 313 } |
| 282 | 314 |
| 283 } // namespace page_load_metrics | 315 } // namespace page_load_metrics |
| OLD | NEW |