Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 // affected performance. | 42 // affected performance. |
| 43 const int kWindowDurationSeconds = 30; | 43 const int kWindowDurationSeconds = 30; |
| 44 | 44 |
| 45 std::string ComposeHistogramName(const std::string& prefix_type, | 45 std::string ComposeHistogramName(const std::string& prefix_type, |
| 46 const std::string& name) { | 46 const std::string& name) { |
| 47 if (prefix_type.empty()) | 47 if (prefix_type.empty()) |
| 48 return std::string("Prerender.") + name; | 48 return std::string("Prerender.") + name; |
| 49 return std::string("Prerender.") + prefix_type + std::string("_") + name; | 49 return std::string("Prerender.") + prefix_type + std::string("_") + name; |
| 50 } | 50 } |
| 51 | 51 |
| 52 std::string GetHistogramName(Origin origin, bool is_wash, | 52 std::string GetHistogramName(Origin origin, const std::string& name) { |
| 53 const std::string& name) { | |
| 54 if (is_wash) | |
| 55 return ComposeHistogramName("wash", name); | |
| 56 | |
| 57 switch (origin) { | 53 switch (origin) { |
| 58 case ORIGIN_OMNIBOX: | 54 case ORIGIN_OMNIBOX: |
| 59 return ComposeHistogramName("omnibox", name); | 55 return ComposeHistogramName("omnibox", name); |
| 60 case ORIGIN_NONE: | 56 case ORIGIN_NONE: |
| 61 return ComposeHistogramName("none", name); | 57 return ComposeHistogramName("none", name); |
| 62 case ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN: | 58 case ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN: |
| 63 return ComposeHistogramName("websame", name); | 59 return ComposeHistogramName("websame", name); |
| 64 case ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN: | 60 case ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN: |
| 65 return ComposeHistogramName("webcross", name); | 61 return ComposeHistogramName("webcross", name); |
| 66 case ORIGIN_EXTERNAL_REQUEST: | 62 case ORIGIN_EXTERNAL_REQUEST: |
| 67 return ComposeHistogramName("externalrequest", name); | 63 return ComposeHistogramName("externalrequest", name); |
| 68 case ORIGIN_INSTANT: | 64 case ORIGIN_INSTANT: |
| 69 return ComposeHistogramName("Instant", name); | 65 return ComposeHistogramName("Instant", name); |
| 70 case ORIGIN_LINK_REL_NEXT: | 66 case ORIGIN_LINK_REL_NEXT: |
| 71 return ComposeHistogramName("webnext", name); | 67 return ComposeHistogramName("webnext", name); |
| 72 case ORIGIN_GWS_PRERENDER: | 68 case ORIGIN_GWS_PRERENDER: |
| 73 return ComposeHistogramName("gws", name); | 69 return ComposeHistogramName("gws", name); |
| 74 case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER: | 70 case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER: |
| 75 return ComposeHistogramName("externalrequestforced", name); | 71 return ComposeHistogramName("externalrequestforced", name); |
| 76 case ORIGIN_OFFLINE: | 72 case ORIGIN_OFFLINE: |
| 77 return ComposeHistogramName("offline", name); | 73 return ComposeHistogramName("offline", name); |
| 78 default: | 74 default: |
| 79 NOTREACHED(); | 75 NOTREACHED(); |
| 80 break; | 76 break; |
| 81 } | 77 } |
| 82 | 78 |
| 83 // Dummy return value to make the compiler happy. | 79 // Dummy return value to make the compiler happy. |
| 84 NOTREACHED(); | 80 NOTREACHED(); |
| 85 return ComposeHistogramName("wash", name); | 81 return ComposeHistogramName("none", name); |
|
pasko
2017/03/24 12:45:23
fun fact: this costs ~26 bytes in android-arm bina
| |
| 86 } | 82 } |
| 87 | 83 |
| 88 bool OriginIsOmnibox(Origin origin) { | 84 bool OriginIsOmnibox(Origin origin) { |
| 89 return origin == ORIGIN_OMNIBOX; | 85 return origin == ORIGIN_OMNIBOX; |
| 90 } | 86 } |
| 91 | 87 |
| 92 const char* FirstContentfulPaintHiddenName(bool was_hidden) { | 88 const char* FirstContentfulPaintHiddenName(bool was_hidden) { |
| 93 return was_hidden ? ".Hidden" : ".Visible"; | 89 return was_hidden ? ".Hidden" : ".Visible"; |
| 94 } | 90 } |
| 95 | 91 |
| 96 } // namespace | 92 } // namespace |
| 97 | 93 |
| 98 // Helper macros for origin-based histogram reporting. All HISTOGRAM arguments | 94 // Helper macro for origin-based histogram reporting. All HISTOGRAM arguments |
| 99 // must be UMA_HISTOGRAM... macros that contain an argument "name" which these | 95 // must be UMA_HISTOGRAM... macros that contain an argument "name" which this |
| 100 // macros will eventually substitute for the actual name used. | 96 // macros will eventually substitute for the actual name used. |
|
pasko
2017/03/24 12:45:23
nit: one more s/macros/macro/
| |
| 101 #define PREFIXED_HISTOGRAM(histogram_name, origin, HISTOGRAM) \ | 97 #define PREFIXED_HISTOGRAM(histogram_name, origin, HISTOGRAM) \ |
| 102 PREFIXED_HISTOGRAM_INTERNAL(origin, IsOriginWash(), HISTOGRAM, histogram_name) | |
| 103 | |
| 104 #define PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT(histogram_name, origin, \ | |
| 105 HISTOGRAM) \ | |
| 106 PREFIXED_HISTOGRAM_INTERNAL(origin, false, HISTOGRAM, histogram_name) | |
| 107 | |
| 108 #define PREFIXED_HISTOGRAM_INTERNAL(origin, wash, HISTOGRAM, histogram_name) \ | |
| 109 do { \ | 98 do { \ |
| 110 { \ | 99 { \ |
| 111 /* Do not rename. HISTOGRAM expects a local variable "name". */ \ | 100 /* Do not rename. HISTOGRAM expects a local variable "name". */ \ |
| 112 std::string name = ComposeHistogramName(std::string(), histogram_name); \ | 101 std::string name = ComposeHistogramName(std::string(), histogram_name); \ |
| 113 HISTOGRAM; \ | 102 HISTOGRAM; \ |
| 114 } \ | 103 } \ |
| 115 /* Do not rename. HISTOGRAM expects a local variable "name". */ \ | 104 /* Do not rename. HISTOGRAM expects a local variable "name". */ \ |
| 116 std::string name = GetHistogramName(origin, wash, histogram_name); \ | 105 std::string name = GetHistogramName(origin, histogram_name); \ |
| 117 /* Branching because HISTOGRAM is caching the histogram into a static. */ \ | 106 /* Branching because HISTOGRAM is caching the histogram into a static. */ \ |
| 118 if (wash) { \ | 107 if (origin == ORIGIN_OMNIBOX) { \ |
| 119 HISTOGRAM; \ | |
| 120 } else if (origin == ORIGIN_OMNIBOX) { \ | |
| 121 HISTOGRAM; \ | 108 HISTOGRAM; \ |
| 122 } else if (origin == ORIGIN_NONE) { \ | 109 } else if (origin == ORIGIN_NONE) { \ |
| 123 HISTOGRAM; \ | 110 HISTOGRAM; \ |
| 124 } else if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN) { \ | 111 } else if (origin == ORIGIN_LINK_REL_PRERENDER_SAMEDOMAIN) { \ |
| 125 HISTOGRAM; \ | 112 HISTOGRAM; \ |
| 126 } else if (origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) { \ | 113 } else if (origin == ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN) { \ |
| 127 HISTOGRAM; \ | 114 HISTOGRAM; \ |
| 128 } else if (origin == ORIGIN_EXTERNAL_REQUEST) { \ | 115 } else if (origin == ORIGIN_EXTERNAL_REQUEST) { \ |
| 129 HISTOGRAM; \ | 116 HISTOGRAM; \ |
| 130 } else if (origin == ORIGIN_INSTANT) { \ | 117 } else if (origin == ORIGIN_INSTANT) { \ |
| 131 HISTOGRAM; \ | 118 HISTOGRAM; \ |
| 132 } else if (origin == ORIGIN_LINK_REL_NEXT) { \ | 119 } else if (origin == ORIGIN_LINK_REL_NEXT) { \ |
| 133 HISTOGRAM; \ | 120 HISTOGRAM; \ |
| 134 } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER) { \ | 121 } else if (origin == ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER) { \ |
| 135 HISTOGRAM; \ | 122 HISTOGRAM; \ |
| 136 } else if (origin == ORIGIN_OFFLINE) { \ | 123 } else if (origin == ORIGIN_OFFLINE) { \ |
| 137 HISTOGRAM; \ | 124 HISTOGRAM; \ |
| 138 } else { \ | 125 } else { \ |
| 139 HISTOGRAM; \ | 126 HISTOGRAM; \ |
| 140 } \ | 127 } \ |
| 141 } while (0) | 128 } while (0) |
| 142 | 129 |
| 143 PrerenderHistograms::PrerenderHistograms() | 130 PrerenderHistograms::PrerenderHistograms() |
| 144 : last_origin_(ORIGIN_MAX), | 131 : seen_any_pageload_(true), seen_pageload_started_after_prerender_(true) {} |
| 145 origin_wash_(false), | |
| 146 seen_any_pageload_(true), | |
| 147 seen_pageload_started_after_prerender_(true) { | |
| 148 } | |
| 149 | 132 |
| 150 void PrerenderHistograms::RecordPrerender(Origin origin, const GURL& url) { | 133 void PrerenderHistograms::RecordPrerender() { |
| 151 // We need to update last_origin_ and origin_wash_. | |
| 152 if (!WithinWindow()) { | |
| 153 // If we are outside a window, this is a fresh start and we are fine, | |
| 154 // and there is no mix. | |
| 155 origin_wash_ = false; | |
| 156 } else { | |
| 157 // If we are inside the last window, there is a mish mash of origins if | |
| 158 // either there was a mish mash before, or the current origin does not match | |
| 159 // the previous one. | |
| 160 if (origin != last_origin_) | |
| 161 origin_wash_ = true; | |
| 162 } | |
| 163 | |
| 164 last_origin_ = origin; | |
| 165 | |
| 166 // If we observe multiple tags within the 30 second window, we will still | 134 // If we observe multiple tags within the 30 second window, we will still |
| 167 // reset the window to begin at the most recent occurrence, so that we will | 135 // reset the window to begin at the most recent occurrence, so that we will |
| 168 // always be in a window in the 30 seconds from each occurrence. | 136 // always be in a window in the 30 seconds from each occurrence. |
| 169 last_prerender_seen_time_ = GetCurrentTimeTicks(); | 137 last_prerender_seen_time_ = GetCurrentTimeTicks(); |
| 170 seen_any_pageload_ = false; | 138 seen_any_pageload_ = false; |
| 171 seen_pageload_started_after_prerender_ = false; | 139 seen_pageload_started_after_prerender_ = false; |
| 172 } | 140 } |
| 173 | 141 |
| 174 void PrerenderHistograms::RecordPrerenderStarted(Origin origin) const { | 142 void PrerenderHistograms::RecordPrerenderStarted(Origin origin) const { |
| 175 if (OriginIsOmnibox(origin)) { | 143 if (OriginIsOmnibox(origin)) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 } | 248 } |
| 281 } | 249 } |
| 282 } | 250 } |
| 283 } | 251 } |
| 284 } | 252 } |
| 285 | 253 |
| 286 void PrerenderHistograms::RecordPerceivedFirstContentfulPaintStatus( | 254 void PrerenderHistograms::RecordPerceivedFirstContentfulPaintStatus( |
| 287 Origin origin, | 255 Origin origin, |
| 288 bool successful, | 256 bool successful, |
| 289 bool was_hidden) { | 257 bool was_hidden) { |
| 290 base::UmaHistogramBoolean( | 258 base::UmaHistogramBoolean(GetHistogramName(origin, "PerceivedTTFCPRecorded") + |
| 291 GetHistogramName(origin, IsOriginWash(), "PerceivedTTFCPRecorded") + | 259 FirstContentfulPaintHiddenName(was_hidden), |
| 292 FirstContentfulPaintHiddenName(was_hidden), | 260 successful); |
| 293 successful); | |
| 294 } | 261 } |
| 295 | 262 |
| 296 void PrerenderHistograms::RecordPageLoadTimeNotSwappedIn( | 263 void PrerenderHistograms::RecordPageLoadTimeNotSwappedIn( |
| 297 Origin origin, | 264 Origin origin, |
| 298 base::TimeDelta page_load_time, | 265 base::TimeDelta page_load_time, |
| 299 const GURL& url) const { | 266 const GURL& url) const { |
| 300 // If the URL to be prerendered is not a http[s] URL, or is a Google URL, | 267 // If the URL to be prerendered is not a http[s] URL, or is a Google URL, |
| 301 // do not record. | 268 // do not record. |
| 302 if (!url.SchemeIsHTTPOrHTTPS() || | 269 if (!url.SchemeIsHTTPOrHTTPS() || |
| 303 google_util::IsGoogleDomainUrl(url, google_util::DISALLOW_SUBDOMAIN, | 270 google_util::IsGoogleDomainUrl(url, google_util::DISALLOW_SUBDOMAIN, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 Origin origin, base::TimeDelta time) const { | 333 Origin origin, base::TimeDelta time) const { |
| 367 PREFIXED_HISTOGRAM( | 334 PREFIXED_HISTOGRAM( |
| 368 "TimeBetweenPrerenderRequests", origin, | 335 "TimeBetweenPrerenderRequests", origin, |
| 369 UMA_HISTOGRAM_TIMES(name, time)); | 336 UMA_HISTOGRAM_TIMES(name, time)); |
| 370 } | 337 } |
| 371 | 338 |
| 372 void PrerenderHistograms::RecordFinalStatus( | 339 void PrerenderHistograms::RecordFinalStatus( |
| 373 Origin origin, | 340 Origin origin, |
| 374 FinalStatus final_status) const { | 341 FinalStatus final_status) const { |
| 375 DCHECK(final_status != FINAL_STATUS_MAX); | 342 DCHECK(final_status != FINAL_STATUS_MAX); |
| 376 PREFIXED_HISTOGRAM_ORIGIN_EXPERIMENT( | 343 PREFIXED_HISTOGRAM( |
| 377 "FinalStatus", origin, | 344 "FinalStatus", origin, |
| 378 UMA_HISTOGRAM_ENUMERATION(name, final_status, FINAL_STATUS_MAX)); | 345 UMA_HISTOGRAM_ENUMERATION(name, final_status, FINAL_STATUS_MAX)); |
| 379 } | 346 } |
| 380 | 347 |
| 381 void PrerenderHistograms::RecordNetworkBytes(Origin origin, | 348 void PrerenderHistograms::RecordNetworkBytes(Origin origin, |
| 382 bool used, | 349 bool used, |
| 383 int64_t prerender_bytes, | 350 int64_t prerender_bytes, |
| 384 int64_t profile_bytes) const { | 351 int64_t profile_bytes) const { |
| 385 const int kHistogramMin = 1; | 352 const int kHistogramMin = 1; |
| 386 const int kHistogramMax = 100000000; // 100M. | 353 const int kHistogramMax = 100000000; // 100M. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 412 | 379 |
| 413 void PrerenderHistograms::RecordPrefetchResponseReceived( | 380 void PrerenderHistograms::RecordPrefetchResponseReceived( |
| 414 Origin origin, | 381 Origin origin, |
| 415 bool is_main_resource, | 382 bool is_main_resource, |
| 416 bool is_redirect, | 383 bool is_redirect, |
| 417 bool is_no_store) const { | 384 bool is_no_store) const { |
| 418 DCHECK(thread_checker_.CalledOnValidThread()); | 385 DCHECK(thread_checker_.CalledOnValidThread()); |
| 419 | 386 |
| 420 int sample = GetResourceType(is_main_resource, is_redirect, is_no_store); | 387 int sample = GetResourceType(is_main_resource, is_redirect, is_no_store); |
| 421 std::string histogram_name = | 388 std::string histogram_name = |
| 422 GetHistogramName(origin, IsOriginWash(), "NoStatePrefetchResponseTypes"); | 389 GetHistogramName(origin, "NoStatePrefetchResponseTypes"); |
| 423 base::UmaHistogramExactLinear(histogram_name, sample, | 390 base::UmaHistogramExactLinear(histogram_name, sample, |
| 424 NO_STATE_PREFETCH_RESPONSE_TYPE_COUNT); | 391 NO_STATE_PREFETCH_RESPONSE_TYPE_COUNT); |
| 425 } | 392 } |
| 426 | 393 |
| 427 void PrerenderHistograms::RecordPrefetchRedirectCount( | 394 void PrerenderHistograms::RecordPrefetchRedirectCount( |
| 428 Origin origin, | 395 Origin origin, |
| 429 bool is_main_resource, | 396 bool is_main_resource, |
| 430 int redirect_count) const { | 397 int redirect_count) const { |
| 431 DCHECK(thread_checker_.CalledOnValidThread()); | 398 DCHECK(thread_checker_.CalledOnValidThread()); |
| 432 | 399 |
| 433 const int kMaxRedirectCount = 10; | 400 const int kMaxRedirectCount = 10; |
| 434 std::string histogram_base_name = base::StringPrintf( | 401 std::string histogram_base_name = base::StringPrintf( |
| 435 "NoStatePrefetch%sResourceRedirects", is_main_resource ? "Main" : "Sub"); | 402 "NoStatePrefetch%sResourceRedirects", is_main_resource ? "Main" : "Sub"); |
| 436 std::string histogram_name = | 403 std::string histogram_name = GetHistogramName(origin, histogram_base_name); |
| 437 GetHistogramName(origin, IsOriginWash(), histogram_base_name); | |
| 438 base::UmaHistogramExactLinear(histogram_name, redirect_count, | 404 base::UmaHistogramExactLinear(histogram_name, redirect_count, |
| 439 kMaxRedirectCount); | 405 kMaxRedirectCount); |
| 440 } | 406 } |
| 441 | 407 |
| 442 void PrerenderHistograms::RecordPrefetchFirstContentfulPaintTime( | 408 void PrerenderHistograms::RecordPrefetchFirstContentfulPaintTime( |
| 443 Origin origin, | 409 Origin origin, |
| 444 bool is_no_store, | 410 bool is_no_store, |
| 445 bool was_hidden, | 411 bool was_hidden, |
| 446 base::TimeDelta time, | 412 base::TimeDelta time, |
| 447 base::TimeDelta prefetch_age) { | 413 base::TimeDelta prefetch_age) { |
| 448 DCHECK(thread_checker_.CalledOnValidThread()); | 414 DCHECK(thread_checker_.CalledOnValidThread()); |
| 449 | 415 |
| 450 if (!prefetch_age.is_zero()) { | 416 if (!prefetch_age.is_zero()) { |
| 451 DCHECK_NE(origin, ORIGIN_NONE); | 417 DCHECK_NE(origin, ORIGIN_NONE); |
| 452 base::UmaHistogramCustomTimes( | 418 base::UmaHistogramCustomTimes(GetHistogramName(origin, "PrefetchAge"), |
| 453 GetHistogramName(origin, IsOriginWash(), "PrefetchAge"), prefetch_age, | 419 prefetch_age, |
| 454 base::TimeDelta::FromMilliseconds(10), base::TimeDelta::FromMinutes(30), | 420 base::TimeDelta::FromMilliseconds(10), |
| 455 50); | 421 base::TimeDelta::FromMinutes(30), 50); |
| 456 } | 422 } |
| 457 | 423 |
| 458 std::string histogram_base_name; | 424 std::string histogram_base_name; |
| 459 if (prefetch_age.is_zero()) { | 425 if (prefetch_age.is_zero()) { |
| 460 histogram_base_name = "PrefetchTTFCP.Reference"; | 426 histogram_base_name = "PrefetchTTFCP.Reference"; |
| 461 } else { | 427 } else { |
| 462 histogram_base_name = prefetch_age < base::TimeDelta::FromMinutes( | 428 histogram_base_name = prefetch_age < base::TimeDelta::FromMinutes( |
| 463 net::HttpCache::kPrefetchReuseMins) | 429 net::HttpCache::kPrefetchReuseMins) |
| 464 ? "PrefetchTTFCP.Warm" | 430 ? "PrefetchTTFCP.Warm" |
| 465 : "PrefetchTTFCP.Cold"; | 431 : "PrefetchTTFCP.Cold"; |
| 466 } | 432 } |
| 467 | 433 |
| 468 histogram_base_name += is_no_store ? ".NoStore" : ".Cacheable"; | 434 histogram_base_name += is_no_store ? ".NoStore" : ".Cacheable"; |
| 469 histogram_base_name += FirstContentfulPaintHiddenName(was_hidden); | 435 histogram_base_name += FirstContentfulPaintHiddenName(was_hidden); |
| 470 std::string histogram_name = | 436 std::string histogram_name = GetHistogramName(origin, histogram_base_name); |
| 471 GetHistogramName(origin, IsOriginWash(), histogram_base_name); | |
| 472 | 437 |
| 473 base::UmaHistogramCustomTimes(histogram_name, time, | 438 base::UmaHistogramCustomTimes(histogram_name, time, |
| 474 base::TimeDelta::FromMilliseconds(10), | 439 base::TimeDelta::FromMilliseconds(10), |
| 475 base::TimeDelta::FromMinutes(2), 50); | 440 base::TimeDelta::FromMinutes(2), 50); |
| 476 } | 441 } |
| 477 | 442 |
| 478 bool PrerenderHistograms::IsOriginWash() const { | |
| 479 if (!WithinWindow()) | |
| 480 return false; | |
| 481 return origin_wash_; | |
| 482 } | |
| 483 | |
| 484 } // namespace prerender | 443 } // namespace prerender |
| OLD | NEW |