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

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: new enum per Randy, updated histograms 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 } 57 }
58 58
59 } // namespace 59 } // namespace
60 60
61 #define PAGE_LOAD_HISTOGRAM(name, sample) \ 61 #define PAGE_LOAD_HISTOGRAM(name, sample) \
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);
69 }
70 68
71 PageLoadTracker::~PageLoadTracker() { 69 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_) 70 if (has_commit_)
78 RecordTimingHistograms(); 71 RecordTimingHistograms();
79 } 72 }
80 73
81 void PageLoadTracker::WebContentsHidden() { 74 void PageLoadTracker::WebContentsHidden() {
82 // Only log the first time we background in a given page load. 75 // Only log the first time we background in a given page load.
83 if (background_time_.is_null()) { 76 if (started_in_foreground_ && background_time_.is_null())
84 background_time_ = base::TimeTicks::Now(); 77 background_time_ = base::TimeTicks::Now();
85 } 78 }
79
80 void PageLoadTracker::WebContentsShown() {
81 // Only log the first time we foreground in a given page load.
82 // Don't log foreground time if we started foregrounded.
83 if (!started_in_foreground_ && foreground_time_.is_null())
84 foreground_time_ = base::TimeTicks::Now();
86 } 85 }
87 86
88 void PageLoadTracker::Commit() { 87 void PageLoadTracker::Commit() {
89 has_commit_ = true; 88 has_commit_ = true;
89 if (started_in_foreground_)
90 RecordCommittedEvent(COMMITTED_LOAD_STARTED_IN_FOREGROUND);
91 else
92 RecordCommittedEvent(COMMITTED_LOAD_STARTED_IN_BACKGROUND);
90 } 93 }
91 94
92 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& timing) { 95 bool PageLoadTracker::UpdateTiming(const PageLoadTiming& new_timing) {
93 // Throw away IPCs that are not relevant to the current navigation. 96 // Throw away IPCs that are not relevant to the current navigation.
94 if (!timing_.navigation_start.is_null() && 97 // A valid timing struct is one that has the same navigation start as the
95 timing_.navigation_start != timing.navigation_start) { 98 // previous one (if the previous one had a navigation start at all).
96 // TODO(csharrison) uma log a counter here 99 bool valid_timing_descendent =
97 return false; 100 timing_.navigation_start.is_null() ||
98 } 101 timing_.navigation_start == new_timing.navigation_start;
99 if (IsValidPageLoadTiming(timing)) { 102 if (IsValidPageLoadTiming(new_timing) && valid_timing_descendent) {
100 timing_ = timing; 103 timing_ = new_timing;
101 return true; 104 return true;
102 } 105 }
106 RecordCommittedEvent(COMMITTED_LOAD_BAD_IPC);
103 return false; 107 return false;
104 } 108 }
105 109
106 void PageLoadTracker::RecordTimingHistograms() { 110 void PageLoadTracker::RecordTimingHistograms() {
107 DCHECK(has_commit_); 111 DCHECK(has_commit_);
108 // This method is similar to how blink converts TimeTicks to epoch time. 112 // This method is similar to how blink converts TimeTicks to epoch time.
109 // There may be slight inaccuracies due to inter-process timestamps, but 113 // There may be slight inaccuracies due to inter-process timestamps, but
110 // this solution is the best we have right now. 114 // this solution is the best we have right now.
111 base::TimeDelta background_delta; 115 base::TimeDelta background_delta;
112 if (started_in_foreground_) { 116 if (started_in_foreground_) {
(...skipping 15 matching lines...) Expand all
128 } 132 }
129 if (!timing_.load_event_start.is_zero()) { 133 if (!timing_.load_event_start.is_zero()) {
130 if (timing_.load_event_start < background_delta) { 134 if (timing_.load_event_start < background_delta) {
131 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired", 135 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired",
132 timing_.load_event_start); 136 timing_.load_event_start);
133 } else { 137 } else {
134 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG", 138 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToLoadEventFired.BG",
135 timing_.load_event_start); 139 timing_.load_event_start);
136 } 140 }
137 } 141 }
138 if (!timing_.first_layout.is_zero()) { 142 if (timing_.first_layout.is_zero()) {
143 RecordCommittedEvent(COMMITTED_LOAD_ABORTED_BEFORE_FIRST_LAYOUT);
144 } else {
139 if (timing_.first_layout < background_delta) { 145 if (timing_.first_layout < background_delta) {
140 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout", 146 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout",
141 timing_.first_layout); 147 timing_.first_layout);
142 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND); 148 RecordCommittedEvent(COMMITTED_LOAD_SUCCESSFUL_FIRST_LAYOUT_FOREGROUND);
143 } else { 149 } else {
144 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG", 150 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstLayout.BG",
145 timing_.first_layout); 151 timing_.first_layout);
146 RecordEvent(PAGE_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND); 152 RecordCommittedEvent(COMMITTED_LOAD_SUCCESSFUL_FIRST_LAYOUT_BACKGROUND);
147 } 153 }
148 } 154 }
149 155 // Log time to first foreground / time to first background. Log counts that we
156 // started a relevant page load in the foreground / background.
157 if (!background_time_.is_null()) {
158 PAGE_LOAD_HISTOGRAM("PageLoad.Timing2.NavigationToFirstBackground",
159 background_delta);
160 } else if (!foreground_time_.is_null()) {
161 PAGE_LOAD_HISTOGRAM(
162 "PageLoad.Timing2.NavigationToFirstForeground",
163 WallTimeFromTimeTicks(foreground_time_) - timing_.navigation_start);
164 }
150 } 165 }
151 166
152 void PageLoadTracker::RecordEvent(PageLoadEvent event) { 167 void PageLoadTracker::RecordProvisionalEvent(ProvisionalLoadEvent event) {
153 UMA_HISTOGRAM_ENUMERATION( 168 UMA_HISTOGRAM_ENUMERATION("PageLoad.Events.Provisional", event,
154 "PageLoad.EventCounts", event, PAGE_LOAD_LAST_ENTRY); 169 PROVISIONAL_LOAD_LAST_ENTRY);
170 }
171
172 void PageLoadTracker::RecordCommittedEvent(CommittedLoadEvent event) {
173 UMA_HISTOGRAM_ENUMERATION("PageLoad.Events.Committed", event,
174 COMMITTED_LOAD_LAST_ENTRY);
155 } 175 }
156 176
157 MetricsWebContentsObserver::MetricsWebContentsObserver( 177 MetricsWebContentsObserver::MetricsWebContentsObserver(
158 content::WebContents* web_contents) 178 content::WebContents* web_contents)
159 : content::WebContentsObserver(web_contents), in_foreground_(false) {} 179 : content::WebContentsObserver(web_contents), in_foreground_(false) {}
160 180
161 MetricsWebContentsObserver::~MetricsWebContentsObserver() {} 181 MetricsWebContentsObserver::~MetricsWebContentsObserver() {}
162 182
163 bool MetricsWebContentsObserver::OnMessageReceived( 183 bool MetricsWebContentsObserver::OnMessageReceived(
164 const IPC::Message& message, 184 const IPC::Message& message,
(...skipping 25 matching lines...) Expand all
190 if (!navigation_handle->IsInMainFrame()) 210 if (!navigation_handle->IsInMainFrame())
191 return; 211 return;
192 212
193 scoped_ptr<PageLoadTracker> finished_nav( 213 scoped_ptr<PageLoadTracker> finished_nav(
194 provisional_loads_.take_and_erase(navigation_handle)); 214 provisional_loads_.take_and_erase(navigation_handle));
195 DCHECK(finished_nav); 215 DCHECK(finished_nav);
196 216
197 // Handle a pre-commit error here. Navigations that result in an error page 217 // Handle a pre-commit error here. Navigations that result in an error page
198 // will be ignored. 218 // will be ignored.
199 if (!navigation_handle->HasCommitted()) { 219 if (!navigation_handle->HasCommitted()) {
200 finished_nav->RecordEvent(PAGE_LOAD_FAILED_BEFORE_COMMIT);
201 if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED) 220 if (navigation_handle->GetNetErrorCode() == net::ERR_ABORTED)
202 finished_nav->RecordEvent(PAGE_LOAD_ABORTED_BEFORE_COMMIT); 221 finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_ABORTED);
222 else
223 finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_FAILED_NON_ABORT);
203 return; 224 return;
204 } 225 }
226 finished_nav->RecordProvisionalEvent(PROVISIONAL_LOAD_COMMITTED);
205 227
206 // Don't treat a same-page nav as a new page load. 228 // Don't treat a same-page nav as a new page load.
207 if (navigation_handle->IsSamePage()) 229 if (navigation_handle->IsSamePage())
208 return; 230 return;
209 231
210 // Eagerly log the previous UMA even if we don't care about the current 232 // Eagerly log the previous UMA even if we don't care about the current
211 // navigation. 233 // navigation.
212 committed_load_.reset(); 234 committed_load_.reset();
213 235
214 if (!IsRelevantNavigation(navigation_handle)) 236 if (!IsRelevantNavigation(navigation_handle))
215 return; 237 return;
216 238
217 committed_load_ = finished_nav.Pass(); 239 committed_load_ = finished_nav.Pass();
218 committed_load_->Commit(); 240 committed_load_->Commit();
219 } 241 }
220 242
221 void MetricsWebContentsObserver::WasShown() { 243 void MetricsWebContentsObserver::WasShown() {
222 in_foreground_ = true; 244 in_foreground_ = true;
245 if (committed_load_)
246 committed_load_->WebContentsShown();
247 for (const auto& kv : provisional_loads_) {
248 kv.second->WebContentsShown();
249 }
223 } 250 }
224 251
225 void MetricsWebContentsObserver::WasHidden() { 252 void MetricsWebContentsObserver::WasHidden() {
226 in_foreground_ = false; 253 in_foreground_ = false;
227 if (committed_load_) 254 if (committed_load_)
228 committed_load_->WebContentsHidden(); 255 committed_load_->WebContentsHidden();
229 for (const auto& kv : provisional_loads_) { 256 for (const auto& kv : provisional_loads_) {
230 kv.second->WebContentsHidden(); 257 kv.second->WebContentsHidden();
231 } 258 }
232 } 259 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 // sure here that we aren't logging UMA for internal pages. 293 // sure here that we aren't logging UMA for internal pages.
267 const GURL& browser_url = web_contents()->GetLastCommittedURL(); 294 const GURL& browser_url = web_contents()->GetLastCommittedURL();
268 return navigation_handle->IsInMainFrame() && 295 return navigation_handle->IsInMainFrame() &&
269 !navigation_handle->IsSamePage() && 296 !navigation_handle->IsSamePage() &&
270 !navigation_handle->IsErrorPage() && 297 !navigation_handle->IsErrorPage() &&
271 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() && 298 navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() &&
272 browser_url.SchemeIsHTTPOrHTTPS(); 299 browser_url.SchemeIsHTTPOrHTTPS();
273 } 300 }
274 301
275 } // namespace page_load_metrics 302 } // namespace page_load_metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698