OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/prerender/prerender_histograms.h" | 5 #include "chrome/browser/prerender/prerender_histograms.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 REDIRECT = 1 << 1, | 29 REDIRECT = 1 << 1, |
30 MAIN_RESOURCE = 1 << 2, | 30 MAIN_RESOURCE = 1 << 2, |
31 NO_STATE_PREFETCH_RESPONSE_TYPE_COUNT = 1 << 3 | 31 NO_STATE_PREFETCH_RESPONSE_TYPE_COUNT = 1 << 3 |
32 }; | 32 }; |
33 | 33 |
34 int GetResourceType(bool is_main_resource, bool is_redirect, bool is_no_store) { | 34 int GetResourceType(bool is_main_resource, bool is_redirect, bool is_no_store) { |
35 return (is_no_store * NO_STORE) + (is_redirect * REDIRECT) + | 35 return (is_no_store * NO_STORE) + (is_redirect * REDIRECT) + |
36 (is_main_resource * MAIN_RESOURCE); | 36 (is_main_resource * MAIN_RESOURCE); |
37 } | 37 } |
38 | 38 |
39 // Time window for which we will record windowed PLTs from the last observed | |
40 // link rel=prefetch tag. This is not intended to be the same as the prerender | |
41 // ttl, it's just intended to be a window during which a prerender has likely | |
42 // affected performance. | |
43 const int kWindowDurationSeconds = 30; | |
44 | |
45 std::string ComposeHistogramName(const std::string& prefix_type, | 39 std::string ComposeHistogramName(const std::string& prefix_type, |
46 const std::string& name) { | 40 const std::string& name) { |
47 if (prefix_type.empty()) | 41 if (prefix_type.empty()) |
48 return std::string("Prerender.") + name; | 42 return std::string("Prerender.") + name; |
49 return std::string("Prerender.") + prefix_type + std::string("_") + name; | 43 return std::string("Prerender.") + prefix_type + std::string("_") + name; |
50 } | 44 } |
51 | 45 |
52 std::string GetHistogramName(Origin origin, const std::string& name) { | 46 std::string GetHistogramName(Origin origin, const std::string& name) { |
53 switch (origin) { | 47 switch (origin) { |
54 case ORIGIN_OMNIBOX: | 48 case ORIGIN_OMNIBOX: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 HISTOGRAM; \ | 114 HISTOGRAM; \ |
121 } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER) { \ | 115 } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER) { \ |
122 HISTOGRAM; \ | 116 HISTOGRAM; \ |
123 } else if (origin == ORIGIN_OFFLINE) { \ | 117 } else if (origin == ORIGIN_OFFLINE) { \ |
124 HISTOGRAM; \ | 118 HISTOGRAM; \ |
125 } else { \ | 119 } else { \ |
126 HISTOGRAM; \ | 120 HISTOGRAM; \ |
127 } \ | 121 } \ |
128 } while (0) | 122 } while (0) |
129 | 123 |
130 PrerenderHistograms::PrerenderHistograms() | 124 PrerenderHistograms::PrerenderHistograms() {} |
131 : seen_any_pageload_(true), seen_pageload_started_after_prerender_(true) {} | |
132 | |
133 void PrerenderHistograms::RecordPrerender() { | |
134 // If we observe multiple tags within the 30 second window, we will still | |
135 // reset the window to begin at the most recent occurrence, so that we will | |
136 // always be in a window in the 30 seconds from each occurrence. | |
137 last_prerender_seen_time_ = GetCurrentTimeTicks(); | |
138 seen_any_pageload_ = false; | |
139 seen_pageload_started_after_prerender_ = false; | |
140 } | |
141 | 125 |
142 void PrerenderHistograms::RecordPrerenderStarted(Origin origin) const { | 126 void PrerenderHistograms::RecordPrerenderStarted(Origin origin) const { |
143 if (OriginIsOmnibox(origin)) { | 127 if (OriginIsOmnibox(origin)) { |
144 UMA_HISTOGRAM_ENUMERATION( | 128 UMA_HISTOGRAM_ENUMERATION( |
145 "Prerender.OmniboxPrerenderCount", 1, 2); | 129 "Prerender.OmniboxPrerenderCount", 1, 2); |
146 } | 130 } |
147 } | 131 } |
148 | 132 |
149 void PrerenderHistograms::RecordConcurrency(size_t prerender_count) const { | |
150 static const size_t kMaxRecordableConcurrency = 20; | |
151 DCHECK_GE(kMaxRecordableConcurrency, Config().max_link_concurrency); | |
152 UMA_HISTOGRAM_ENUMERATION( | |
153 base::StringPrintf("Prerender.PrerenderCountOf%" PRIuS "Max", | |
154 kMaxRecordableConcurrency), | |
155 prerender_count, kMaxRecordableConcurrency + 1); | |
156 } | |
157 | |
158 void PrerenderHistograms::RecordUsedPrerender(Origin origin) const { | 133 void PrerenderHistograms::RecordUsedPrerender(Origin origin) const { |
159 if (OriginIsOmnibox(origin)) { | 134 if (OriginIsOmnibox(origin)) { |
160 UMA_HISTOGRAM_ENUMERATION( | 135 UMA_HISTOGRAM_ENUMERATION( |
161 "Prerender.OmniboxNavigationsUsedPrerenderCount", 1, 2); | 136 "Prerender.OmniboxNavigationsUsedPrerenderCount", 1, 2); |
162 } | 137 } |
163 } | 138 } |
164 | 139 |
165 void PrerenderHistograms::RecordTimeSinceLastRecentVisit( | 140 void PrerenderHistograms::RecordTimeSinceLastRecentVisit( |
166 Origin origin, | 141 Origin origin, |
167 base::TimeDelta delta) const { | 142 base::TimeDelta delta) const { |
168 PREFIXED_HISTOGRAM( | 143 PREFIXED_HISTOGRAM( |
169 "TimeSinceLastRecentVisit", origin, | 144 "TimeSinceLastRecentVisit", origin, |
170 UMA_HISTOGRAM_TIMES(name, delta)); | 145 UMA_HISTOGRAM_TIMES(name, delta)); |
171 } | 146 } |
172 | 147 |
173 base::TimeTicks PrerenderHistograms::GetCurrentTimeTicks() const { | |
174 return base::TimeTicks::Now(); | |
175 } | |
176 | |
177 // Helper macro for histograms. | |
178 #define RECORD_PLT(tag, perceived_page_load_time) \ | |
179 PREFIXED_HISTOGRAM( \ | |
180 tag, origin, \ | |
181 UMA_HISTOGRAM_CUSTOM_TIMES( \ | |
182 name, \ | |
183 perceived_page_load_time, \ | |
184 base::TimeDelta::FromMilliseconds(10), \ | |
185 base::TimeDelta::FromSeconds(60), \ | |
186 100)) | |
187 | |
188 // Summary of all histograms Perceived PLT histograms: | |
189 // (all prefixed PerceivedPLT) | |
190 // PerceivedPLT -- Perceived Pageloadtimes (PPLT) for all pages in the group. | |
191 // ...Windowed -- PPLT for pages in the 30s after a prerender is created. | |
192 // ...FirstAfterMiss -- First page to finish loading after a prerender, which | |
193 // is different from the page that was prerendered. | |
194 // ...FirstAfterMissNonOverlapping -- Same as FirstAfterMiss, but only | |
195 // triggering for the first page to finish after the prerender that also started | |
196 // after the prerender started. | |
197 // ...FirstAfterMissBoth -- pages meeting | |
198 // FirstAfterMiss AND FirstAfterMissNonOverlapping | |
199 // ...FirstAfterMissAnyOnly -- pages meeting | |
200 // FirstAfterMiss but NOT FirstAfterMissNonOverlapping | |
201 // ..FirstAfterMissNonOverlappingOnly -- pages meeting | |
202 // FirstAfterMissNonOverlapping but NOT FirstAfterMiss | |
203 | |
204 void PrerenderHistograms::RecordPerceivedPageLoadTime( | |
205 Origin origin, | |
206 base::TimeDelta perceived_page_load_time, | |
207 NavigationType navigation_type, | |
208 const GURL& url) { | |
209 if (!url.SchemeIsHTTPOrHTTPS()) | |
210 return; | |
211 bool within_window = WithinWindow(); | |
212 bool is_google_url = | |
213 google_util::IsGoogleDomainUrl(url, google_util::DISALLOW_SUBDOMAIN, | |
214 google_util::ALLOW_NON_STANDARD_PORTS); | |
215 RECORD_PLT("PerceivedPLT", perceived_page_load_time); | |
216 if (within_window) | |
217 RECORD_PLT("PerceivedPLTWindowed", perceived_page_load_time); | |
218 if (navigation_type != NAVIGATION_TYPE_NORMAL) { | |
219 DCHECK(navigation_type == NAVIGATION_TYPE_PRERENDERED); | |
220 seen_any_pageload_ = true; | |
221 seen_pageload_started_after_prerender_ = true; | |
222 } else if (within_window) { | |
223 if (!is_google_url) { | |
224 bool recorded_any = false; | |
225 bool recorded_non_overlapping = false; | |
226 if (!seen_any_pageload_) { | |
227 seen_any_pageload_ = true; | |
228 RECORD_PLT("PerceivedPLTFirstAfterMiss", perceived_page_load_time); | |
229 recorded_any = true; | |
230 } | |
231 if (!seen_pageload_started_after_prerender_ && | |
232 perceived_page_load_time <= GetTimeSinceLastPrerender()) { | |
233 seen_pageload_started_after_prerender_ = true; | |
234 RECORD_PLT("PerceivedPLTFirstAfterMissNonOverlapping", | |
235 perceived_page_load_time); | |
236 recorded_non_overlapping = true; | |
237 } | |
238 if (recorded_any || recorded_non_overlapping) { | |
239 if (recorded_any && recorded_non_overlapping) { | |
240 RECORD_PLT("PerceivedPLTFirstAfterMissBoth", | |
241 perceived_page_load_time); | |
242 } else if (recorded_any) { | |
243 RECORD_PLT("PerceivedPLTFirstAfterMissAnyOnly", | |
244 perceived_page_load_time); | |
245 } else if (recorded_non_overlapping) { | |
246 RECORD_PLT("PerceivedPLTFirstAfterMissNonOverlappingOnly", | |
247 perceived_page_load_time); | |
248 } | |
249 } | |
250 } | |
251 } | |
252 } | |
253 | |
254 void PrerenderHistograms::RecordPerceivedFirstContentfulPaintStatus( | 148 void PrerenderHistograms::RecordPerceivedFirstContentfulPaintStatus( |
255 Origin origin, | 149 Origin origin, |
256 bool successful, | 150 bool successful, |
257 bool was_hidden) { | 151 bool was_hidden) const { |
258 base::UmaHistogramBoolean(GetHistogramName(origin, "PerceivedTTFCPRecorded") + | 152 base::UmaHistogramBoolean(GetHistogramName(origin, "PerceivedTTFCPRecorded") + |
259 FirstContentfulPaintHiddenName(was_hidden), | 153 FirstContentfulPaintHiddenName(was_hidden), |
260 successful); | 154 successful); |
261 } | 155 } |
262 | 156 |
263 void PrerenderHistograms::RecordPageLoadTimeNotSwappedIn( | |
264 Origin origin, | |
265 base::TimeDelta page_load_time, | |
266 const GURL& url) const { | |
267 // If the URL to be prerendered is not a http[s] URL, or is a Google URL, | |
268 // do not record. | |
269 if (!url.SchemeIsHTTPOrHTTPS() || | |
270 google_util::IsGoogleDomainUrl(url, google_util::DISALLOW_SUBDOMAIN, | |
271 google_util::ALLOW_NON_STANDARD_PORTS)) { | |
272 return; | |
273 } | |
274 RECORD_PLT("PrerenderNotSwappedInPLT", page_load_time); | |
275 } | |
276 | |
277 void PrerenderHistograms::RecordPercentLoadDoneAtSwapin(Origin origin, | 157 void PrerenderHistograms::RecordPercentLoadDoneAtSwapin(Origin origin, |
278 double fraction) const { | 158 double fraction) const { |
279 if (fraction < 0.0 || fraction > 1.0) | 159 if (fraction < 0.0 || fraction > 1.0) |
280 return; | 160 return; |
281 int percentage = static_cast<int>(fraction * 100); | 161 int percentage = static_cast<int>(fraction * 100); |
282 if (percentage < 0 || percentage > 100) | 162 if (percentage < 0 || percentage > 100) |
283 return; | 163 return; |
284 PREFIXED_HISTOGRAM("PercentLoadDoneAtSwapin", | 164 PREFIXED_HISTOGRAM("PercentLoadDoneAtSwapin", |
285 origin, UMA_HISTOGRAM_PERCENTAGE(name, percentage)); | 165 origin, UMA_HISTOGRAM_PERCENTAGE(name, percentage)); |
286 } | 166 } |
287 | 167 |
288 base::TimeDelta PrerenderHistograms::GetTimeSinceLastPrerender() const { | |
289 return base::TimeTicks::Now() - last_prerender_seen_time_; | |
290 } | |
291 | |
292 bool PrerenderHistograms::WithinWindow() const { | |
293 if (last_prerender_seen_time_.is_null()) | |
294 return false; | |
295 return GetTimeSinceLastPrerender() <= | |
296 base::TimeDelta::FromSeconds(kWindowDurationSeconds); | |
297 } | |
298 | |
299 void PrerenderHistograms::RecordTimeUntilUsed( | 168 void PrerenderHistograms::RecordTimeUntilUsed( |
300 Origin origin, | 169 Origin origin, |
301 base::TimeDelta time_until_used) const { | 170 base::TimeDelta time_until_used) const { |
302 PREFIXED_HISTOGRAM( | 171 PREFIXED_HISTOGRAM( |
303 "TimeUntilUsed2", origin, | 172 "TimeUntilUsed2", origin, |
304 UMA_HISTOGRAM_CUSTOM_TIMES( | 173 UMA_HISTOGRAM_CUSTOM_TIMES( |
305 name, | 174 name, |
306 time_until_used, | 175 time_until_used, |
307 base::TimeDelta::FromMilliseconds(10), | 176 base::TimeDelta::FromMilliseconds(10), |
308 base::TimeDelta::FromMinutes(30), | 177 base::TimeDelta::FromMinutes(30), |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 std::string histogram_name = GetHistogramName(origin, histogram_base_name); | 272 std::string histogram_name = GetHistogramName(origin, histogram_base_name); |
404 base::UmaHistogramExactLinear(histogram_name, redirect_count, | 273 base::UmaHistogramExactLinear(histogram_name, redirect_count, |
405 kMaxRedirectCount); | 274 kMaxRedirectCount); |
406 } | 275 } |
407 | 276 |
408 void PrerenderHistograms::RecordPrefetchFirstContentfulPaintTime( | 277 void PrerenderHistograms::RecordPrefetchFirstContentfulPaintTime( |
409 Origin origin, | 278 Origin origin, |
410 bool is_no_store, | 279 bool is_no_store, |
411 bool was_hidden, | 280 bool was_hidden, |
412 base::TimeDelta time, | 281 base::TimeDelta time, |
413 base::TimeDelta prefetch_age) { | 282 base::TimeDelta prefetch_age) const { |
414 DCHECK(thread_checker_.CalledOnValidThread()); | 283 DCHECK(thread_checker_.CalledOnValidThread()); |
415 | 284 |
416 if (!prefetch_age.is_zero()) { | 285 if (!prefetch_age.is_zero()) { |
417 DCHECK_NE(origin, ORIGIN_NONE); | 286 DCHECK_NE(origin, ORIGIN_NONE); |
418 base::UmaHistogramCustomTimes(GetHistogramName(origin, "PrefetchAge"), | 287 base::UmaHistogramCustomTimes(GetHistogramName(origin, "PrefetchAge"), |
419 prefetch_age, | 288 prefetch_age, |
420 base::TimeDelta::FromMilliseconds(10), | 289 base::TimeDelta::FromMilliseconds(10), |
421 base::TimeDelta::FromMinutes(30), 50); | 290 base::TimeDelta::FromMinutes(30), 50); |
422 } | 291 } |
423 | 292 |
(...skipping 10 matching lines...) Expand all Loading... |
434 histogram_base_name += is_no_store ? ".NoStore" : ".Cacheable"; | 303 histogram_base_name += is_no_store ? ".NoStore" : ".Cacheable"; |
435 histogram_base_name += FirstContentfulPaintHiddenName(was_hidden); | 304 histogram_base_name += FirstContentfulPaintHiddenName(was_hidden); |
436 std::string histogram_name = GetHistogramName(origin, histogram_base_name); | 305 std::string histogram_name = GetHistogramName(origin, histogram_base_name); |
437 | 306 |
438 base::UmaHistogramCustomTimes(histogram_name, time, | 307 base::UmaHistogramCustomTimes(histogram_name, time, |
439 base::TimeDelta::FromMilliseconds(10), | 308 base::TimeDelta::FromMilliseconds(10), |
440 base::TimeDelta::FromMinutes(2), 50); | 309 base::TimeDelta::FromMinutes(2), 50); |
441 } | 310 } |
442 | 311 |
443 } // namespace prerender | 312 } // namespace prerender |
OLD | NEW |