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

Side by Side Diff: components/page_load_metrics/browser/metrics_web_contents_observer.cc

Issue 1384213002: Page Abort Events for relevant navigations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More events + bg/fg metrics Created 5 years, 2 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 "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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698