#include "chrome/renderer/page_load_histograms.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/time.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/prerender/prerender_helper.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPerformance.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
using WebKit::WebDataSource;
using WebKit::WebFrame;
using WebKit::WebPerformance;
using WebKit::WebString;
using base::Time;
using base::TimeDelta;
using content::DocumentState;
const size_t kPLTCount = 100;
namespace {
TimeDelta kPLTMin() {
return TimeDelta::FromMilliseconds(10);
}
TimeDelta kPLTMax() {
return TimeDelta::FromMinutes(10);
}
#define PLT_HISTOGRAM(name, sample) \
UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, kPLTMin(), kPLTMax(), kPLTCount);
URLPattern::SchemeMasks GetSupportedSchemeType(const GURL& url) {
if (url.SchemeIs("http"))
return URLPattern::SCHEME_HTTP;
else if (url.SchemeIs("https"))
return URLPattern::SCHEME_HTTPS;
return static_cast<URLPattern::SchemeMasks>(0);
}
void DumpPerformanceTiming(const WebPerformance& performance,
DocumentState* document_state) {
Time request = document_state->request_time();
Time navigation_start = Time::FromDoubleT(performance.navigationStart());
Time request_start = Time::FromDoubleT(performance.requestStart());
Time response_start = Time::FromDoubleT(performance.responseStart());
Time load_event_start = Time::FromDoubleT(performance.loadEventStart());
Time load_event_end = Time::FromDoubleT(performance.loadEventEnd());
Time begin = (request.is_null() ? navigation_start : request_start);
DCHECK(!navigation_start.is_null());
DCHECK(!request_start.is_null());
DCHECK(!response_start.is_null());
if (document_state->web_timing_histograms_recorded())
return;
document_state->set_web_timing_histograms_recorded(true);
if (!load_event_start.is_null()) {
PLT_HISTOGRAM("PLT.PT_BeginToFinishDoc", load_event_start - begin);
PLT_HISTOGRAM("PLT.PT_CommitToFinishDoc",
load_event_start - response_start);
}
if (!load_event_end.is_null()) {
PLT_HISTOGRAM("PLT.PT_BeginToFinish", load_event_end - begin);
PLT_HISTOGRAM("PLT.PT_CommitToFinish", load_event_end - response_start);
PLT_HISTOGRAM("PLT.PT_RequestToFinish", load_event_end - navigation_start);
PLT_HISTOGRAM("PLT.PT_StartToFinish", load_event_end - request_start);
}
if (!load_event_start.is_null() && !load_event_end.is_null()) {
PLT_HISTOGRAM("PLT.PT_FinishDocToFinish",
load_event_end - load_event_start);
}
PLT_HISTOGRAM("PLT.PT_BeginToCommit", response_start - begin);
PLT_HISTOGRAM("PLT.PT_RequestToStart", request_start - navigation_start);
PLT_HISTOGRAM("PLT.PT_StartToCommit", response_start - request_start);
}
enum MissingStartType {
START_MISSING = 0x1,
COMMIT_MISSING = 0x2,
NAV_START_MISSING = 0x4,
MISSING_START_TYPE_MAX = 0x8
};
enum AbandonType {
FINISH_DOC_MISSING = 0x1,
FINISH_ALL_LOADS_MISSING = 0x2,
LOAD_EVENT_START_MISSING = 0x4,
LOAD_EVENT_END_MISSING = 0x8,
ABANDON_TYPE_MAX = 0x10
};
}
PageLoadHistograms::PageLoadHistograms(content::RenderView* render_view)
: content::RenderViewObserver(render_view),
cross_origin_access_count_(0),
same_origin_access_count_(0) {
}
void PageLoadHistograms::Dump(WebFrame* frame) {
if (!frame || frame->parent())
return;
URLPattern::SchemeMasks scheme_type =
GetSupportedSchemeType(frame->document().url());
if (scheme_type == 0)
return;
if (frame->dataSource()->response().isMultipartPayload())
return;
DocumentState* document_state =
DocumentState::FromDataSource(frame->dataSource());
DumpPerformanceTiming(frame->performance(), document_state);
if (document_state->load_histograms_recorded())
return;
Time start = document_state->start_load_time();
Time commit = document_state->commit_load_time();
Time navigation_start =
Time::FromDoubleT(frame->performance().navigationStart());
int missing_start_type = 0;
missing_start_type |= start.is_null() ? START_MISSING : 0;
missing_start_type |= commit.is_null() ? COMMIT_MISSING : 0;
missing_start_type |= navigation_start.is_null() ? NAV_START_MISSING : 0;
UMA_HISTOGRAM_ENUMERATION("PLT.MissingStart", missing_start_type,
MISSING_START_TYPE_MAX);
if (missing_start_type)
return;
Time request = document_state->request_time();
Time first_paint = document_state->first_paint_time();
Time first_paint_after_load = document_state->first_paint_after_load_time();
Time finish_doc = document_state->finish_document_load_time();
Time finish_all_loads = document_state->finish_load_time();
Time load_event_start =
Time::FromDoubleT(frame->performance().loadEventStart());
Time load_event_end = Time::FromDoubleT(frame->performance().loadEventEnd());
int abandon_type = 0;
abandon_type |= finish_doc.is_null() ? FINISH_DOC_MISSING : 0;
abandon_type |= finish_all_loads.is_null() ? FINISH_ALL_LOADS_MISSING : 0;
abandon_type |= load_event_start.is_null() ? LOAD_EVENT_START_MISSING : 0;
abandon_type |= load_event_end.is_null() ? LOAD_EVENT_END_MISSING : 0;
UMA_HISTOGRAM_ENUMERATION("PLT.AbandonType", abandon_type, ABANDON_TYPE_MAX);
bool abandoned_page = finish_doc.is_null();
if (abandoned_page) {
finish_doc = Time::Now();
document_state->set_finish_document_load_time(finish_doc);
}
if (finish_all_loads.is_null()) {
finish_all_loads = Time::Now();
document_state->set_finish_load_time(finish_all_loads);
} else {
DCHECK(!abandoned_page);
if (abandoned_page)
return;
}
document_state->set_load_histograms_recorded(true);
Time begin = request.is_null() ? start : request;
TimeDelta begin_to_finish_doc = finish_doc - begin;
TimeDelta begin_to_finish_all_loads = finish_all_loads - begin;
TimeDelta start_to_finish_all_loads = finish_all_loads - start;
TimeDelta start_to_commit = commit - start;
DocumentState::LoadType load_type = document_state->load_type();
UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned", abandoned_page ? 1 : 0, 2);
UMA_HISTOGRAM_ENUMERATION("PLT.LoadType", load_type,
DocumentState::kLoadTypeMax);
PLT_HISTOGRAM("PLT.StartToCommit", start_to_commit);
PLT_HISTOGRAM("PLT.CommitToFinishDoc", finish_doc - commit);
PLT_HISTOGRAM("PLT.FinishDocToFinish", finish_all_loads - finish_doc);
PLT_HISTOGRAM("PLT.BeginToCommit", commit - begin);
PLT_HISTOGRAM("PLT.StartToFinish", start_to_finish_all_loads);
if (!request.is_null()) {
PLT_HISTOGRAM("PLT.RequestToStart", start - request);
PLT_HISTOGRAM("PLT.RequestToFinish", finish_all_loads - request);
}
PLT_HISTOGRAM("PLT.CommitToFinish", finish_all_loads - commit);
if (!first_paint.is_null()) {
if (begin <= first_paint) {
PLT_HISTOGRAM("PLT.BeginToFirstPaint", first_paint - begin);
}
DCHECK(commit <= first_paint);
PLT_HISTOGRAM("PLT.CommitToFirstPaint", first_paint - commit);
}
if (!first_paint_after_load.is_null()) {
if (begin <= first_paint_after_load) {
PLT_HISTOGRAM("PLT.BeginToFirstPaintAfterLoad",
first_paint_after_load - begin);
}
DCHECK(commit <= first_paint_after_load);
PLT_HISTOGRAM("PLT.CommitToFirstPaintAfterLoad",
first_paint_after_load - commit);
DCHECK(finish_all_loads <= first_paint_after_load);
PLT_HISTOGRAM("PLT.FinishToFirstPaintAfterLoad",
first_paint_after_load - finish_all_loads);
}
PLT_HISTOGRAM("PLT.BeginToFinishDoc", begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish", begin_to_finish_all_loads);
switch (load_type) {
case DocumentState::UNDEFINED_LOAD:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_UndefLoad", begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_UndefLoad", begin_to_finish_all_loads);
break;
case DocumentState::RELOAD:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_Reload", begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_Reload", begin_to_finish_all_loads);
break;
case DocumentState::HISTORY_LOAD:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_HistoryLoad", begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_HistoryLoad", begin_to_finish_all_loads);
break;
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_NormalLoad", begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_NormalLoad", begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadNormal",
begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadNormal",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadReload",
begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadReload",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadStaleOk",
begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadStaleOk",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_ONLY:
PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadCacheOnly",
begin_to_finish_doc);
PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadCacheOnly",
begin_to_finish_all_loads);
break;
default:
break;
}
static const bool use_dns_histogram =
base::FieldTrialList::TrialExists("DnsImpact");
if (use_dns_histogram) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "DnsImpact"),
abandoned_page ? 1 : 0, 2);
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.LoadType", "DnsImpact"),
load_type, DocumentState::kLoadTypeMax);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "DnsImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "DnsImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "DnsImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "DnsImpact"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool prefetching_fieldtrial =
base::FieldTrialList::TrialExists("Prefetch");
if (prefetching_fieldtrial) {
if (document_state->was_prefetcher()) {
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc_ContentPrefetcher", "Prefetch"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_ContentPrefetcher", "Prefetch"),
begin_to_finish_all_loads);
}
if (document_state->was_referred_by_prefetcher()) {
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc_ContentPrefetcherReferrer", "Prefetch"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_ContentPrefetcherReferrer", "Prefetch"),
begin_to_finish_all_loads);
}
UMA_HISTOGRAM_ENUMERATION(base::FieldTrial::MakeName(
"PLT.Abandoned", "Prefetch"),
abandoned_page ? 1 : 0, 2);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc", "Prefetch"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish", "Prefetch"),
begin_to_finish_all_loads);
}
static const bool prerendering_fieldtrial =
base::FieldTrialList::TrialExists("Prerender");
if (prerendering_fieldtrial) {
if (document_state->was_prefetcher()) {
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc_ContentPrefetcher", "Prerender"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_ContentPrefetcher", "Prerender"),
begin_to_finish_all_loads);
}
if (document_state->was_referred_by_prefetcher()) {
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc_ContentPrefetcherReferrer", "Prerender"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_ContentPrefetcherReferrer", "Prerender"),
begin_to_finish_all_loads);
}
UMA_HISTOGRAM_ENUMERATION(base::FieldTrial::MakeName(
"PLT.Abandoned", "Prerender"),
abandoned_page ? 1 : 0, 2);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinishDoc", "Prerender"),
begin_to_finish_doc);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish", "Prerender"),
begin_to_finish_all_loads);
}
static const bool connect_backup_jobs_fieldtrial =
base::FieldTrialList::TrialExists("ConnnectBackupJobs");
if (connect_backup_jobs_fieldtrial) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "ConnnectBackupJobs"),
abandoned_page ? 1 : 0, 2);
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.LoadType", "ConnnectBackupJobs"),
load_type, DocumentState::kLoadTypeMax);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "ConnnectBackupJobs"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "ConnnectBackupJobs"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "ConnnectBackupJobs"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "ConnnectBackupJobs"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool use_connection_impact_histogram =
base::FieldTrialList::TrialExists("ConnCountImpact");
if (use_connection_impact_histogram) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "ConnCountImpact"),
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "ConnCountImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "ConnCountImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "ConnCountImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "ConnCountImpact"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool use_idle_socket_timeout_histogram =
base::FieldTrialList::TrialExists("IdleSktToImpact");
if (use_idle_socket_timeout_histogram) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "IdleSktToImpact"),
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "IdleSktToImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "IdleSktToImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "IdleSktToImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "IdleSktToImpact"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool use_proxy_connection_impact_histogram =
base::FieldTrialList::TrialExists("ProxyConnectionImpact");
if (use_proxy_connection_impact_histogram) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "ProxyConnectionImpact"),
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "ProxyConnectionImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "ProxyConnectionImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "ProxyConnectionImpact"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "ProxyConnectionImpact"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool use_sdch_histogram =
base::FieldTrialList::TrialExists("GlobalSdch");
if (use_sdch_histogram) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.LoadType", "GlobalSdch"),
load_type, DocumentState::kLoadTypeMax);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "GlobalSdch"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "GlobalSdch"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadReload", "GlobalSdch"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadStaleOk", "GlobalSdch"),
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_ONLY:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadCacheOnly", "GlobalSdch"),
begin_to_finish_all_loads);
break;
default:
break;
}
}
chrome::ChromeContentRendererClient* client =
static_cast<chrome::ChromeContentRendererClient*>(
content::GetContentClient()->renderer());
const bool use_adblock_histogram = client->IsAdblockInstalled();
if (use_adblock_histogram) {
UMA_HISTOGRAM_ENUMERATION(
"PLT.Abandoned_ExtensionAdblock",
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_NormalLoad_ExtensionAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadNormal_ExtensionAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadReload_ExtensionAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadStaleOk_ExtensionAdblock",
begin_to_finish_all_loads);
break;
default:
break;
}
}
const bool use_adblockplus_histogram = client->IsAdblockPlusInstalled();
if (use_adblockplus_histogram) {
UMA_HISTOGRAM_ENUMERATION(
"PLT.Abandoned_ExtensionAdblockPlus",
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_NormalLoad_ExtensionAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadNormal_ExtensionAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadReload_ExtensionAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadStaleOk_ExtensionAdblockPlus",
begin_to_finish_all_loads);
break;
default:
break;
}
}
const bool use_webrequest_adblock_histogram =
client->IsAdblockWithWebRequestInstalled();
if (use_webrequest_adblock_histogram) {
UMA_HISTOGRAM_ENUMERATION(
"PLT.Abandoned_ExtensionWebRequestAdblock",
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_NormalLoad_ExtensionWebRequestAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestAdblock",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestAdblock",
begin_to_finish_all_loads);
break;
default:
break;
}
}
const bool use_webrequest_adblockplus_histogram =
client->IsAdblockPlusWithWebRequestInstalled();
if (use_webrequest_adblockplus_histogram) {
UMA_HISTOGRAM_ENUMERATION(
"PLT.Abandoned_ExtensionWebRequestAdblockPlus",
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_NormalLoad_ExtensionWebRequestAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestAdblockPlus",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestAdblockPlus",
begin_to_finish_all_loads);
break;
default:
break;
}
}
const bool use_webrequest_other_histogram =
client->IsOtherExtensionWithWebRequestInstalled();
if (use_webrequest_other_histogram) {
UMA_HISTOGRAM_ENUMERATION(
"PLT.Abandoned_ExtensionWebRequestOther",
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_NormalLoad_ExtensionWebRequestOther",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadNormal_ExtensionWebRequestOther",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_RELOAD:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadReload_ExtensionWebRequestOther",
begin_to_finish_all_loads);
break;
case DocumentState::LINK_LOAD_CACHE_STALE_OK:
PLT_HISTOGRAM(
"PLT.BeginToFinish_LinkLoadStaleOk_ExtensionWebRequestOther",
begin_to_finish_all_loads);
break;
default:
break;
}
}
static const bool use_spdy_histogram =
base::FieldTrialList::TrialExists("SpdyImpact");
if (use_spdy_histogram) {
static bool in_spdy_trial = base::FieldTrialList::Find(
"SpdyImpact")->group_name() == "npn_with_spdy";
static bool in_http_trial = base::FieldTrialList::Find(
"SpdyImpact")->group_name() == "npn_with_http";
bool spdy_trial_success = document_state->was_fetched_via_spdy() ?
in_spdy_trial : in_http_trial;
if (spdy_trial_success) {
if (scheme_type == URLPattern::SCHEME_HTTPS &&
document_state->was_npn_negotiated()) {
UMA_HISTOGRAM_ENUMERATION(
base::FieldTrial::MakeName("PLT.Abandoned", "SpdyImpact"),
abandoned_page ? 1 : 0, 2);
switch (load_type) {
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "SpdyImpact"),
begin_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToFinish_LinkLoadNormal", "SpdyImpact"),
start_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToCommit_LinkLoadNormal", "SpdyImpact"),
start_to_commit);
break;
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "SpdyImpact"),
begin_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToFinish_NormalLoad", "SpdyImpact"),
start_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToCommit_NormalLoad", "SpdyImpact"),
start_to_commit);
break;
default:
break;
}
}
if (scheme_type == URLPattern::SCHEME_HTTP &&
document_state->was_alternate_protocol_available()) {
if (!document_state->was_npn_negotiated()) {
switch (load_type) {
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.StartToFinish_LinkLoadNormal_AlternateProtocol_http",
start_to_finish_all_loads);
PLT_HISTOGRAM(
"PLT.StartToCommit_LinkLoadNormal_AlternateProtocol_http",
start_to_commit);
break;
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.StartToFinish_NormalLoad_AlternateProtocol_http",
start_to_finish_all_loads);
PLT_HISTOGRAM(
"PLT.StartToCommit_NormalLoad_AlternateProtocol_http",
start_to_commit);
break;
default:
break;
}
} else if (document_state->was_fetched_via_spdy()) {
switch (load_type) {
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(
"PLT.StartToFinish_LinkLoadNormal_AlternateProtocol_spdy",
start_to_finish_all_loads);
PLT_HISTOGRAM(
"PLT.StartToCommit_LinkLoadNormal_AlternateProtocol_spdy",
start_to_commit);
break;
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(
"PLT.StartToFinish_NormalLoad_AlternateProtocol_spdy",
start_to_finish_all_loads);
PLT_HISTOGRAM(
"PLT.StartToCommit_NormalLoad_AlternateProtocol_spdy",
start_to_commit);
break;
default:
break;
}
}
}
}
}
if (document_state->was_fetched_via_spdy()) {
switch (load_type) {
case DocumentState::LINK_LOAD_NORMAL:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_LinkLoadNormal", "SpdyCwnd"),
begin_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToFinish_LinkLoadNormal", "SpdyCwnd"),
start_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToCommit_LinkLoadNormal", "SpdyCwnd"),
start_to_commit);
break;
case DocumentState::NORMAL_LOAD:
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.BeginToFinish_NormalLoad", "SpdyCwnd"),
begin_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToFinish_NormalLoad", "SpdyCwnd"),
start_to_finish_all_loads);
PLT_HISTOGRAM(base::FieldTrial::MakeName(
"PLT.StartToCommit_NormalLoad", "SpdyCwnd"),
start_to_commit);
break;
default:
break;
}
}
if (document_state->was_fetched_via_proxy()) {
if (scheme_type == URLPattern::SCHEME_HTTPS) {
PLT_HISTOGRAM("PLT.StartToFinish.Proxy.https", start_to_finish_all_loads);
UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned.Proxy.https",
abandoned_page ? 1 : 0, 2);
} else {
DCHECK(scheme_type == URLPattern::SCHEME_HTTP);
PLT_HISTOGRAM("PLT.StartToFinish.Proxy.http", start_to_finish_all_loads);
UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned.Proxy.http",
abandoned_page ? 1 : 0, 2);
}
} else {
if (scheme_type == URLPattern::SCHEME_HTTPS) {
PLT_HISTOGRAM("PLT.StartToFinish.NoProxy.https",
start_to_finish_all_loads);
UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned.NoProxy.https",
abandoned_page ? 1 : 0, 2);
} else {
DCHECK(scheme_type == URLPattern::SCHEME_HTTP);
PLT_HISTOGRAM("PLT.StartToFinish.NoProxy.http",
start_to_finish_all_loads);
UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned.NoProxy.http",
abandoned_page ? 1 : 0, 2);
}
}
UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithCrossSiteFrameAccess",
cross_origin_access_count_);
UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithSameSiteFrameAccess",
same_origin_access_count_);
LogPageLoadTime(document_state, frame->dataSource());
prerender::PrerenderHelper::RecordHistograms(render_view(),
finish_all_loads,
begin_to_finish_all_loads);
content::RenderThread::Get()->UpdateHistograms(
content::kHistogramSynchronizerReservedSequenceNumber);
}
void PageLoadHistograms::ResetCrossFramePropertyAccess() {
cross_origin_access_count_ = 0;
same_origin_access_count_ = 0;
}
void PageLoadHistograms::FrameWillClose(WebFrame* frame) {
Dump(frame);
}
void PageLoadHistograms::ClosePage() {
Dump(render_view()->GetWebView()->mainFrame());
ResetCrossFramePropertyAccess();
}
void PageLoadHistograms::LogPageLoadTime(const DocumentState* document_state,
const WebDataSource* ds) const {
if (logging::LOG_INFO < logging::GetMinLogLevel())
return;
DCHECK(document_state);
DCHECK(ds);
GURL url(ds->request().url());
Time start = document_state->start_load_time();
Time finish = document_state->finish_load_time();
VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms "
<< url.spec();
}