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" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ | 62 UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, \ |
63 base::TimeDelta::FromMilliseconds(10), \ | 63 base::TimeDelta::FromMilliseconds(10), \ |
64 base::TimeDelta::FromMinutes(10), 100) | 64 base::TimeDelta::FromMinutes(10), 100) |
65 | 65 |
66 PageLoadTracker::PageLoadTracker(bool in_foreground) | 66 PageLoadTracker::PageLoadTracker(bool in_foreground) |
67 : has_commit_(false), started_in_foreground_(in_foreground) { | 67 : has_commit_(false), started_in_foreground_(in_foreground) { |
68 RecordEvent(PAGE_LOAD_STARTED); | 68 RecordEvent(PAGE_LOAD_STARTED); |
69 } | 69 } |
70 | 70 |
71 PageLoadTracker::~PageLoadTracker() { | 71 PageLoadTracker::~PageLoadTracker() { |
72 // Even a load that failed a provisional load should log | |
73 // that it aborted before first layout. | |
74 if (timing_.first_layout.is_zero()) | |
75 RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); | |
76 | |
77 if (has_commit_) | 72 if (has_commit_) |
78 RecordTimingHistograms(); | 73 RecordTimingHistograms(); |
79 } | 74 } |
80 | 75 |
81 void PageLoadTracker::WebContentsHidden() { | 76 void PageLoadTracker::WebContentsHidden() { |
82 // Only log the first time we background in a given page load. | 77 // Only log the first time we background in a given page load. |
83 if (background_time_.is_null()) { | 78 if (background_time_.is_null()) { |
84 background_time_ = base::TimeTicks::Now(); | 79 background_time_ = base::TimeTicks::Now(); |
85 } | 80 } |
86 } | 81 } |
87 | 82 |
83 void PageLoadTracker::WebContentsShown() { | |
84 // Only log the first time we foreground in a given page load. | |
85 // Don't log foreground time if we started foregrounded. | |
Randy Smith (Not in Mondays)
2015/10/06 19:24:00
I'm confused by this sentence. If we started fore
Charlie Harrison
2015/10/06 19:35:36
You're right this code could be more clear. Later
| |
86 if (foreground_time_.is_null()) { | |
87 foreground_time_ = base::TimeTicks::Now(); | |
88 } | |
89 } | |
90 | |
88 void PageLoadTracker::Commit() { | 91 void PageLoadTracker::Commit() { |
89 has_commit_ = true; | 92 has_commit_ = true; |
93 // We only know page relevancy post-commit. | |
94 if (started_in_foreground_) | |
95 RecordEvent(PAGE_LOAD_RELEVANT_STARTED_IN_FOREGROUND); | |
96 else | |
97 RecordEvent(PAGE_LOAD_RELEVANT_STARTED_IN_BACKGROUND); | |
90 } | 98 } |
91 | 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 bool valid_timing_descendent = timing_.navigation_start.is_null() || |
Randy Smith (Not in Mondays)
2015/10/06 19:24:00
nit, suggestion: I dislike creating temporary vari
| |
95 timing_.navigation_start != timing.navigation_start) { | 103 timing_.navigation_start == timing.navigation_start; |
96 // TODO(csharrison) uma log a counter here | 104 if (IsValidPageLoadTiming(timing) && valid_timing_descendent) { |
97 return false; | |
98 } | |
99 if (IsValidPageLoadTiming(timing)) { | |
100 timing_ = timing; | 105 timing_ = timing; |
101 return true; | 106 return true; |
102 } | 107 } |
108 RecordEvent(PAGE_LOAD_BAD_IPC); | |
103 return false; | 109 return false; |
104 } | 110 } |
105 | 111 |
106 void PageLoadTracker::RecordTimingHistograms() { | 112 void PageLoadTracker::RecordTimingHistograms() { |
107 DCHECK(has_commit_); | 113 DCHECK(has_commit_); |
108 // This method is similar to how blink converts TimeTicks to epoch time. | 114 // This method is similar to how blink converts TimeTicks to epoch time. |
109 // There may be slight inaccuracies due to inter-process timestamps, but | 115 // There may be slight inaccuracies due to inter-process timestamps, but |
110 // this solution is the best we have right now. | 116 // this solution is the best we have right now. |
111 base::TimeDelta background_delta; | 117 base::TimeDelta background_delta; |
112 if (started_in_foreground_) { | 118 if (started_in_foreground_) { |
(...skipping 15 matching lines...) Expand all Loading... | |
128 } | 134 } |
129 if (!timing_.load_event_start.is_zero()) { | 135 if (!timing_.load_event_start.is_zero()) { |
130 if (timing_.load_event_start < background_delta) { | 136 if (timing_.load_event_start < background_delta) { |
131 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired", | 137 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired", |
132 timing_.load_event_start); | 138 timing_.load_event_start); |
133 } else { | 139 } else { |
134 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", | 140 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", |
135 timing_.load_event_start); | 141 timing_.load_event_start); |
136 } | 142 } |
137 } | 143 } |
138 if (!timing_.first_layout.is_zero()) { | 144 if (timing_.first_layout.is_zero()) { |
145 RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); | |
146 RecordEvent(PAGE_LOAD_RELEVANT_ABORTED_BEFORE_FIRST_LAYOUT); | |
147 } else { | |
139 if (timing_.first_layout < background_delta) { | 148 if (timing_.first_layout < background_delta) { |
140 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", | 149 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", |
141 timing_.first_layout); | 150 timing_.first_layout); |
142 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); | 151 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); |
143 } else { | 152 } else { |
144 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", | 153 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", |
145 timing_.first_layout); | 154 timing_.first_layout); |
146 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); | 155 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); |
147 } | 156 } |
148 } | 157 } |
149 | 158 // Log time to first foreground / time to first background. Log counts that we |
159 // started a relevant page load in the foreground / background. | |
160 if (started_in_foreground_ && !background_time_.is_null()) { | |
161 PAGE_LOAD_HISTOGRAM( | |
162 "PageLoad.Timing2.NavigationToFirstBackground", background_delta); | |
163 } else if (!started_in_foreground_ && !foreground_time_.is_null()) { | |
164 PAGE_LOAD_HISTOGRAM( | |
165 "PageLoad.Timing2.NavigationToFirstForeground", | |
166 WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start); | |
167 } | |
150 } | 168 } |
151 | 169 |
152 void PageLoadTracker::RecordEvent(PageLoadEvent event) { | 170 void PageLoadTracker::RecordEvent(PageLoadEvent event) { |
153 UMA_HISTOGRAM_ENUMERATION( | 171 UMA_HISTOGRAM_ENUMERATION( |
154 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); | 172 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); |
155 } | 173 } |
156 | 174 |
157 MetricsWebContentsObserver::MetricsWebContentsObserver( | 175 MetricsWebContentsObserver::MetricsWebContentsObserver( |
158 content::WebContents* web_contents) | 176 content::WebContents* web_contents) |
159 : content::WebContentsObserver(web_contents), in_foreground_(false) {} | 177 : content::WebContentsObserver(web_contents), in_foreground_(false) {} |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 return; | 209 return; |
192 | 210 |
193 scoped_ptr<PageLoadTracker> finished_nav( | 211 scoped_ptr<PageLoadTracker> finished_nav( |
194 provisional_loads_.take_and_erase(navigation_handle)); | 212 provisional_loads_.take_and_erase(navigation_handle)); |
195 DCHECK(finished_nav); | 213 DCHECK(finished_nav); |
196 | 214 |
197 // Handle a pre-commit error here. Navigations that result in an error page | 215 // Handle a pre-commit error here. Navigations that result in an error page |
198 // will be ignored. | 216 // will be ignored. |
199 if (!navigation_handle->HasCommitted()) { | 217 if (!navigation_handle->HasCommitted()) { |
200 finished_nav->RecordEvent(PAGE_LOAD_FAILED_BEFORE_COMMIT); | 218 finished_nav->RecordEvent(PAGE_LOAD_FAILED_BEFORE_COMMIT); |
201 if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED) | 219 if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED) { |
202 finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_COMMIT); | 220 finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_COMMIT); |
221 finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_FIRST_LAYOUT); | |
222 } | |
203 return; | 223 return; |
204 } | 224 } |
205 | 225 |
206 // Don't treat a same-page nav as a new page load. | 226 // Don't treat a same-page nav as a new page load. |
207 if (navigation_handle->IsSamePage()) | 227 if (navigation_handle->IsSamePage()) |
208 return; | 228 return; |
209 | 229 |
210 // Eagerly log the previous UMA even if we don't care about the current | 230 // Eagerly log the previous UMA even if we don't care about the current |
211 // navigation. | 231 // navigation. |
212 committed_load_.reset(); | 232 committed_load_.reset(); |
213 | 233 |
214 if (!IsRelevantNavigation(navigation_handle)) | 234 if (!IsRelevantNavigation(navigation_handle)) |
215 return; | 235 return; |
216 | 236 |
217 committed_load_ = finished_nav.Pass(); | 237 committed_load_ = finished_nav.Pass(); |
218 committed_load_->Commit(); | 238 committed_load_->Commit(); |
219 } | 239 } |
220 | 240 |
221 void MetricsWebContentsObserver::WasShown() { | 241 void MetricsWebContentsObserver::WasShown() { |
222 in_foreground_ = true; | 242 in_foreground_ = true; |
243 if (committed_load_) | |
244 committed_load_->WebContentsShown(); | |
245 for (const auto& kv : provisional_loads_) { | |
246 kv.second->WebContentsShown(); | |
247 } | |
223 } | 248 } |
224 | 249 |
225 void MetricsWebContentsObserver::WasHidden() { | 250 void MetricsWebContentsObserver::WasHidden() { |
226 in_foreground_ = false; | 251 in_foreground_ = false; |
227 if (committed_load_) | 252 if (committed_load_) |
228 committed_load_->WebContentsHidden(); | 253 committed_load_->WebContentsHidden(); |
229 for (const auto& kv : provisional_loads_) { | 254 for (const auto& kv : provisional_loads_) { |
230 kv.second->WebContentsHidden(); | 255 kv.second->WebContentsHidden(); |
231 } | 256 } |
232 } | 257 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 // sure here that we aren't logging UMA for internal pages. | 291 // sure here that we aren't logging UMA for internal pages. |
267 const GURL& browser_url = web_contents()->GetLastCommittedURL(); | 292 const GURL& browser_url = web_contents()->GetLastCommittedURL(); |
268 return navigation_handle->IsInMainFrame() && | 293 return navigation_handle->IsInMainFrame() && |
269 !navigation_handle->IsSamePage() && | 294 !navigation_handle->IsSamePage() && |
270 !navigation_handle->IsErrorPage() && | 295 !navigation_handle->IsErrorPage() && |
271 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && | 296 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && |
272 browser_url.SchemeIsHTTPOrHTTPS(); | 297 browser_url.SchemeIsHTTPOrHTTPS(); |
273 } | 298 } |
274 | 299 |
275 } // namespace page_load_metrics | 300 } // namespace page_load_metrics |
OLD | NEW |