summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/renderer/navigation_state.h16
-rw-r--r--chrome/renderer/page_load_histograms.cc697
-rw-r--r--chrome/renderer/page_load_histograms.h59
-rw-r--r--chrome/renderer/render_view.cc716
-rw-r--r--chrome/renderer/render_view.h15
6 files changed, 769 insertions, 736 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index af9c6fd..de923833 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -130,6 +130,8 @@
'renderer/page_click_listener.h',
'renderer/page_click_tracker.cc',
'renderer/page_click_tracker.h',
+ 'renderer/page_load_histograms.cc',
+ 'renderer/page_load_histograms.h',
'renderer/password_autocomplete_manager.cc',
'renderer/password_autocomplete_manager.h',
'renderer/pepper_devices.cc',
diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h
index d9cee3e..6041389 100644
--- a/chrome/renderer/navigation_state.h
+++ b/chrome/renderer/navigation_state.h
@@ -152,18 +152,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
first_paint_after_load_time_ = value;
}
- // Info about the URL used as the target of this navigation.
- URLPattern::SchemeMasks scheme_type() const { return scheme_type_; }
- void set_scheme_type(URLPattern::SchemeMasks scheme_type) {
- scheme_type_ = scheme_type;
- }
-
- // True iff the histograms for the associated frame have been dumped.
- bool load_histograms_recorded() const { return load_histograms_recorded_; }
- void set_load_histograms_recorded(bool value) {
- load_histograms_recorded_ = value;
- }
-
// True if we have already processed the "DidCommitLoad" event for this
// request. Used by session history.
bool request_committed() const { return request_committed_; }
@@ -281,8 +269,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
: transition_type_(transition_type),
load_type_(UNDEFINED_LOAD),
request_time_(request_time),
- scheme_type_(static_cast<URLPattern::SchemeMasks>(0)),
- load_histograms_recorded_(false),
request_committed_(false),
is_content_initiated_(is_content_initiated),
pending_page_id_(pending_page_id),
@@ -311,8 +297,6 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
base::Time finish_load_time_;
base::Time first_paint_time_;
base::Time first_paint_after_load_time_;
- URLPattern::SchemeMasks scheme_type_;
- bool load_histograms_recorded_;
bool request_committed_;
bool is_content_initiated_;
int32 pending_page_id_;
diff --git a/chrome/renderer/page_load_histograms.cc b/chrome/renderer/page_load_histograms.cc
new file mode 100644
index 0000000..30e8a4d
--- /dev/null
+++ b/chrome/renderer/page_load_histograms.cc
@@ -0,0 +1,697 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#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/chrome_constants.h"
+#include "chrome/renderer/navigation_state.h"
+#include "chrome/renderer/render_thread.h"
+#include "googleurl/src/gurl.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
+
+using base::Time;
+using base::TimeDelta;
+using WebKit::WebDataSource;
+using WebKit::WebFrame;
+
+static const TimeDelta kPLTMin(TimeDelta::FromMilliseconds(10));
+static const TimeDelta kPLTMax(TimeDelta::FromMinutes(10));
+static const size_t kPLTCount(100);
+
+#define PLT_HISTOGRAM(name, sample) \
+ UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, kPLTMin, kPLTMax, kPLTCount);
+
+// Returns the scheme type of the given URL if its type is one for which we
+// dump page load histograms. Otherwise returns NULL.
+static 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);
+}
+
+PageLoadHistograms::PageLoadHistograms()
+ : has_dumped_(false),
+ cross_origin_access_count_(0),
+ same_origin_access_count_(0) {
+}
+
+void PageLoadHistograms::Dump(WebFrame* frame) {
+ // We only dump histograms for main frames.
+ // In the future, it may be interesting to tag subframes and dump them too.
+ if (!frame || frame->parent())
+ return;
+
+ // If we've already dumped, do nothing.
+ // This simple bool works because we only dump for the main frame.
+ if (has_dumped_)
+ return;
+
+ // Only dump for supported schemes.
+ URLPattern::SchemeMasks scheme_type = GetSupportedSchemeType(frame->url());
+ if (scheme_type == 0)
+ return;
+
+ // Configuration for PLT related histograms.
+ NavigationState* navigation_state =
+ NavigationState::FromDataSource(frame->dataSource());
+
+ // Collect measurement times.
+ Time start = navigation_state->start_load_time();
+ if (start.is_null())
+ return; // Probably very premature abandonment of page.
+ Time commit = navigation_state->commit_load_time();
+ if (commit.is_null())
+ return; // Probably very premature abandonment of page.
+
+ // We properly handle null values for the next 3 variables.
+ Time request = navigation_state->request_time();
+ Time first_paint = navigation_state->first_paint_time();
+ Time first_paint_after_load = navigation_state->first_paint_after_load_time();
+ Time finish_doc = navigation_state->finish_document_load_time();
+ Time finish_all_loads = navigation_state->finish_load_time();
+
+ // Handle case where user hits "stop" or "back" before loading completely.
+ bool abandoned_page = finish_doc.is_null();
+ if (abandoned_page) {
+ finish_doc = Time::Now();
+ navigation_state->set_finish_document_load_time(finish_doc);
+ }
+
+ // TODO(jar): We should really discriminate the definition of "abandon" more
+ // finely. We should have:
+ // abandon_before_document_loaded
+ // abandon_before_onload_fired
+
+ if (finish_all_loads.is_null()) {
+ finish_all_loads = Time::Now();
+ navigation_state->set_finish_load_time(finish_all_loads);
+ } else {
+ DCHECK(!abandoned_page); // How can the doc have finished but not the page?
+ if (!abandoned_page)
+ return; // Don't try to record a stat which is broken.
+ }
+
+ has_dumped_ = true;
+
+ // Note: Client side redirects will have no request time.
+ 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;
+
+ NavigationState::LoadType load_type = navigation_state->load_type();
+
+ // The above code sanitized all values of times, in preparation for creating
+ // actual histograms. The remainder of this code could be run at destructor
+ // time for the navigation_state, since all data is intact.
+
+ // Aggregate PLT data across all link types.
+ UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned", abandoned_page ? 1 : 0, 2);
+ UMA_HISTOGRAM_ENUMERATION("PLT.LoadType", load_type,
+ NavigationState::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()) {
+ DCHECK(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()) {
+ DCHECK(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);
+
+ // Load type related histograms.
+ switch (load_type) {
+ case NavigationState::UNDEFINED_LOAD:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_UndefLoad", begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_UndefLoad", begin_to_finish_all_loads);
+ break;
+ case NavigationState::RELOAD:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_Reload", begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_Reload", begin_to_finish_all_loads);
+ break;
+ case NavigationState::HISTORY_LOAD:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_HistoryLoad", begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_HistoryLoad", begin_to_finish_all_loads);
+ break;
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_NormalLoad", begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_NormalLoad", begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadNormal",
+ begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadNormal",
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadReload",
+ begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadReload",
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::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 NavigationState::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;
+ }
+
+ // Histograms to determine if DNS prefetching has an impact on PLT.
+ static bool use_dns_histogram(base::FieldTrialList::Find("DnsImpact") &&
+ !base::FieldTrialList::Find("DnsImpact")->group_name().empty());
+ 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, NavigationState::kLoadTypeMax);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "DnsImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "DnsImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "DnsImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "DnsImpact"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine if content prefetching has an impact on PLT.
+ static const bool prefetching_fieldtrial =
+ base::FieldTrialList::Find("Prefetch") &&
+ !base::FieldTrialList::Find("Prefetch")->group_name().empty();
+ if (prefetching_fieldtrial) {
+ if (navigation_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 (navigation_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);
+ }
+
+ // Histograms to determine if backup connection jobs have an impact on PLT.
+ static const bool connect_backup_jobs_fieldtrial(
+ base::FieldTrialList::Find("ConnnectBackupJobs") &&
+ !base::FieldTrialList::Find("ConnnectBackupJobs")->group_name().empty());
+ 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, NavigationState::kLoadTypeMax);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "ConnnectBackupJobs"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "ConnnectBackupJobs"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "ConnnectBackupJobs"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "ConnnectBackupJobs"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine if the number of connections has an
+ // impact on PLT.
+ // TODO(jar): Consider removing the per-link-type versions. We
+ // really only need LINK_LOAD_NORMAL and NORMAL_LOAD.
+ static bool use_connection_impact_histogram(
+ base::FieldTrialList::Find("ConnCountImpact") &&
+ !base::FieldTrialList::Find("ConnCountImpact")->group_name().empty());
+ if (use_connection_impact_histogram) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.Abandoned", "ConnCountImpact"),
+ abandoned_page ? 1 : 0, 2);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "ConnCountImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "ConnCountImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "ConnCountImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "ConnCountImpact"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine effect of idle socket timeout.
+ static bool use_idle_socket_timeout_histogram(
+ base::FieldTrialList::Find("IdleSktToImpact") &&
+ !base::FieldTrialList::Find("IdleSktToImpact")->group_name().empty());
+ if (use_idle_socket_timeout_histogram) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.Abandoned", "IdleSktToImpact"),
+ abandoned_page ? 1 : 0, 2);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "IdleSktToImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "IdleSktToImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "IdleSktToImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "IdleSktToImpact"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine effect of number of connections per proxy.
+ static bool use_proxy_connection_impact_histogram(
+ base::FieldTrialList::Find("ProxyConnectionImpact") &&
+ !base::FieldTrialList::Find(
+ "ProxyConnectionImpact")->group_name().empty());
+ if (use_proxy_connection_impact_histogram) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.Abandoned", "ProxyConnectionImpact"),
+ abandoned_page ? 1 : 0, 2);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "ProxyConnectionImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "ProxyConnectionImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "ProxyConnectionImpact"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "ProxyConnectionImpact"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine if SDCH has an impact.
+ // TODO(jar): Consider removing per-link load types and the enumeration.
+ static bool use_sdch_histogram(base::FieldTrialList::Find("GlobalSdch") &&
+ !base::FieldTrialList::Find("GlobalSdch")->group_name().empty());
+ if (use_sdch_histogram) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.LoadType", "GlobalSdch"),
+ load_type, NavigationState::kLoadTypeMax);
+ switch (load_type) {
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "GlobalSdch"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "GlobalSdch"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "GlobalSdch"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "GlobalSdch"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_ONLY:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadCacheOnly", "GlobalSdch"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to determine if cache size has an impact on PLT.
+ static bool use_cache_histogram1(base::FieldTrialList::Find("CacheSize") &&
+ !base::FieldTrialList::Find("CacheSize")->group_name().empty());
+ if (use_cache_histogram1 && NavigationState::LINK_LOAD_NORMAL <= load_type &&
+ NavigationState::LINK_LOAD_CACHE_ONLY >= load_type) {
+ // TODO(mbelshe): Do we really want BeginToFinishDoc here? It seems like
+ // StartToFinish or BeginToFinish would be better.
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinishDoc_LinkLoad", "CacheSize"), begin_to_finish_doc);
+ }
+
+ // Histograms to determine if cache throttling has an impact on PLT.
+ static bool use_cache_histogram2(
+ base::FieldTrialList::Find("CacheThrottle") &&
+ !base::FieldTrialList::Find("CacheThrottle")->group_name().empty());
+ if (use_cache_histogram2) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.Abandoned", "CacheThrottle"),
+ abandoned_page ? 1 : 0, 2);
+ switch (load_type) {
+ case NavigationState::RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_Reload", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::HISTORY_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_HistoryLoad", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_RELOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadReload", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_STALE_OK:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadStaleOk", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ case NavigationState::LINK_LOAD_CACHE_ONLY:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadCacheOnly", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ break;
+ default:
+ break;
+ }
+ if (NavigationState::RELOAD <= load_type &&
+ NavigationState::LINK_LOAD_CACHE_ONLY >= load_type) {
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish", "CacheThrottle"),
+ begin_to_finish_all_loads);
+ }
+ }
+
+ // For the SPDY field trials, we need to verify that the page loaded was
+ // the type we requested:
+ // if we asked for a SPDY request, we got a SPDY request
+ // if we asked for a HTTP request, we got a HTTP request
+ // Due to spdy version mismatches, it is possible that we ask for SPDY
+ // but didn't get SPDY.
+ static bool use_spdy_histogram(base::FieldTrialList::Find("SpdyImpact") &&
+ !base::FieldTrialList::Find("SpdyImpact")->group_name().empty());
+ if (use_spdy_histogram) {
+ // We take extra effort to only compute these once.
+ 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 = navigation_state->was_fetched_via_spdy() ?
+ in_spdy_trial : in_http_trial;
+ if (spdy_trial_success) {
+ // Histograms to determine if SPDY has an impact for https traffic.
+ // TODO(mbelshe): After we've seen the difference between BeginToFinish
+ // and StartToFinish, consider removing one or the other.
+ if (scheme_type == URLPattern::SCHEME_HTTPS &&
+ navigation_state->was_npn_negotiated()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ base::FieldTrial::MakeName("PLT.Abandoned", "SpdyImpact"),
+ abandoned_page ? 1 : 0, 2);
+ switch (load_type) {
+ case NavigationState::LINK_LOAD_NORMAL:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
+ begin_to_finish_all_loads);
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.StartToFinish_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
+ start_to_finish_all_loads);
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.StartToCommit_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
+ start_to_commit);
+ break;
+ case NavigationState::NORMAL_LOAD:
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.BeginToFinish_NormalLoad_SpdyTrial", "SpdyImpact"),
+ begin_to_finish_all_loads);
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.StartToFinish_NormalLoad_SpdyTrial", "SpdyImpact"),
+ start_to_finish_all_loads);
+ PLT_HISTOGRAM(base::FieldTrial::MakeName(
+ "PLT.StartToCommit_NormalLoad_SpdyTrial", "SpdyImpact"),
+ start_to_commit);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Histograms to compare the impact of alternate protocol over http
+ // traffic: when spdy is used vs. when http is used.
+ if (scheme_type == URLPattern::SCHEME_HTTP &&
+ navigation_state->was_alternate_protocol_available()) {
+ if (!navigation_state->was_npn_negotiated()) {
+ // This means that even there is alternate protocols for npn_http or
+ // npn_spdy, they are not taken (due to the base::FieldTrial).
+ switch (load_type) {
+ case NavigationState::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 NavigationState::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 (navigation_state->was_fetched_via_spdy()) {
+ switch (load_type) {
+ case NavigationState::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 NavigationState::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;
+ }
+ }
+ }
+ }
+ }
+
+ // Record page load time and abandonment rates for proxy cases.
+ if (navigation_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);
+ }
+ }
+
+ // Site isolation metrics.
+ UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithCrossSiteFrameAccess",
+ cross_origin_access_count_);
+ UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithSameSiteFrameAccess",
+ same_origin_access_count_);
+ ResetCrossFramePropertyAccess();
+
+ // Log the PLT to the info log.
+ LogPageLoadTime(navigation_state, frame->dataSource());
+
+ // Since there are currently no guarantees that renderer histograms will be
+ // sent to the browser, we initiate a PostTask here to be sure that we send
+ // the histograms we generated. Without this call, pages that don't have an
+ // on-close-handler might generate data that is lost when the renderer is
+ // shutdown abruptly (perchance because the user closed the tab).
+ // TODO(jar) BUG=33233: This needs to be moved to a PostDelayedTask, and it
+ // should post when the onload is complete, so that it doesn't interfere with
+ // the next load.
+ if (RenderThread::current()) {
+ RenderThread::current()->SendHistograms(
+ chrome::kHistogramSynchronizerReservedSequenceNumber);
+ }
+}
+
+void PageLoadHistograms::IncrementCrossFramePropertyAccess(bool cross_origin) {
+ if (cross_origin)
+ cross_origin_access_count_++;
+ else
+ same_origin_access_count_++;
+}
+
+void PageLoadHistograms::ResetCrossFramePropertyAccess() {
+ cross_origin_access_count_ = 0;
+ same_origin_access_count_ = 0;
+}
+
+void PageLoadHistograms::LogPageLoadTime(const NavigationState* state,
+ const WebDataSource* ds) const {
+ // Because this function gets called on every page load,
+ // take extra care to optimize it away if logging is turned off.
+ if (logging::LOG_INFO < logging::GetMinLogLevel())
+ return;
+
+ DCHECK(state);
+ DCHECK(ds);
+ GURL url(ds->request().url());
+ Time start = state->start_load_time();
+ Time finish = state->finish_load_time();
+ // TODO(mbelshe): should we log more stats?
+ VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms "
+ << url.spec();
+}
diff --git a/chrome/renderer/page_load_histograms.h b/chrome/renderer/page_load_histograms.h
new file mode 100644
index 0000000..7045089
--- /dev/null
+++ b/chrome/renderer/page_load_histograms.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_PAGE_LOAD_HISTOGRAMS_H_
+#define CHROME_RENDERER_PAGE_LOAD_HISTOGRAMS_H_
+
+#include "base/basictypes.h"
+
+class NavigationState;
+
+namespace WebKit {
+class WebDataSource;
+class WebFrame;
+}
+
+class PageLoadHistograms {
+ public:
+ PageLoadHistograms();
+
+ // Dump all page load histograms appropriate for the given frame.
+ //
+ // This method will only dump once-per-instance, so it is safe to call
+ // multiple times.
+ //
+ // The time points we keep are
+ // request: time document was requested by user
+ // start: time load of document started
+ // commit: time load of document started
+ // finish_document: main document loaded, before onload()
+ // finish_all_loads: after onload() and all resources are loaded
+ // first_paint: first paint performed
+ // first_paint_after_load: first paint performed after load is finished
+ // begin: request if it was user requested, start otherwise
+ //
+ // It's possible for the request time not to be set, if a client
+ // redirect had been done (the user never requested the page)
+ // Also, it's possible to load a page without ever laying it out
+ // so first_paint and first_paint_after_load can be 0.
+ void Dump(WebKit::WebFrame* frame);
+
+ void IncrementCrossFramePropertyAccess(bool cross_origin);
+
+ private:
+ void ResetCrossFramePropertyAccess();
+ void LogPageLoadTime(const NavigationState* state,
+ const WebKit::WebDataSource* ds) const;
+
+ bool has_dumped_;
+
+ // Site isolation metric counts.
+ // These are per-page-load counts, reset to 0 after they are dumped.
+ int cross_origin_access_count_;
+ int same_origin_access_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(PageLoadHistograms);
+};
+
+#endif // CHROME_RENDERER_PAGE_LOAD_HISTOGRAMS_H_
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 09caae4..8c09d90 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -15,7 +15,6 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
-#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
#include "base/process_util.h"
@@ -69,6 +68,7 @@
#include "chrome/renderer/navigation_state.h"
#include "chrome/renderer/notification_provider.h"
#include "chrome/renderer/page_click_tracker.h"
+#include "chrome/renderer/page_load_histograms.h"
#include "chrome/renderer/password_autocomplete_manager.h"
#include "chrome/renderer/plugin_channel_host.h"
#include "chrome/renderer/print_web_view_helper.h"
@@ -474,8 +474,6 @@ RenderView::RenderView(RenderThreadBase* render_thread,
has_document_tag_(false),
#endif
document_tag_(0),
- cross_origin_access_count_(0),
- same_origin_access_count_(0),
target_url_status_(TARGET_NONE),
spelling_panel_visible_(false),
view_type_(ViewType::INVALID),
@@ -2622,18 +2620,7 @@ void RenderView::willClose(WebFrame* frame) {
WebDataSource* ds = frame->dataSource();
NavigationState* navigation_state = NavigationState::FromDataSource(ds);
- if (!frame->parent()) {
- const GURL& url = frame->url();
- // Ensure state contains scheme.
- if (url.SchemeIs("http"))
- navigation_state->set_scheme_type(URLPattern::SCHEME_HTTP);
- else if (url.SchemeIs("https"))
- navigation_state->set_scheme_type(URLPattern::SCHEME_HTTPS);
-
- // Dump will only be provided when scheme is http or https.
- DumpLoadHistograms();
- }
-
+ page_load_histograms_.Dump(frame);
navigation_state->user_script_idle_scheduler()->Cancel();
// TODO(jhawkins): Remove once frameDetached is called by WebKit.
@@ -3539,10 +3526,7 @@ void RenderView::logCrossFramePropertyAccess(WebFrame* frame,
const WebString& property_name,
unsigned long long event_id) {
// TODO(johnnyg): track the individual properties and repeat event_ids.
- if (cross_origin)
- cross_origin_access_count_++;
- else
- same_origin_access_count_++;
+ page_load_histograms_.IncrementCrossFramePropertyAccess(cross_origin);
}
void RenderView::didChangeContentsSize(WebFrame* frame, const WebSize& size) {
@@ -4652,30 +4636,12 @@ void RenderView::OnClosePage(const ViewMsg_ClosePage_Params& params) {
// revisited to avoid having two ways to close a page. Having a single way
// to close that can run onunload is also useful for fixing
// http://b/issue?id=753080.
- WebFrame* main_frame = webview()->mainFrame();
- if (main_frame) {
- const GURL& url = main_frame->url();
- // TODO(davemoore) this code should be removed once willClose() gets
- // called when a page is destroyed. DumpLoadHistograms() is safe to call
- // multiple times for the same frame, but it will simplify things.
-
- // Ensure state contains scheme.
- NavigationState* navigation_state =
- NavigationState::FromDataSource(main_frame->dataSource());
- if (url.SchemeIs("http"))
- navigation_state->set_scheme_type(URLPattern::SCHEME_HTTP);
- else if (url.SchemeIs("https"))
- navigation_state->set_scheme_type(URLPattern::SCHEME_HTTPS);
-
- // Dump will only be provided when scheme is http or https.
- DumpLoadHistograms();
- }
+ // TODO(davemoore) This code should be removed once willClose() gets
+ // called when a page is destroyed. page_load_histograms_.Dump() is safe
+ // to call multiple times for the same frame, but it will simplify things.
+ page_load_histograms_.Dump(webview()->mainFrame());
webview()->dispatchUnloadEvent();
- // Reset stats
- cross_origin_access_count_ = 0;
- same_origin_access_count_ = 0;
-
// Just echo back the params in the ACK.
Send(new ViewHostMsg_ClosePage_ACK(routing_id_, params));
}
@@ -4955,674 +4921,6 @@ void RenderView::OnExtensionMessageInvoke(const std::string& extension_id,
extension_id, function_name, args, this, event_url);
}
-// Dump all load time histograms.
-//
-// The time points we keep are
-// request: time document was requested by user
-// start: time load of document started
-// commit: time load of document started
-// finish_document: main document loaded, before onload()
-// finish_all_loads: after onload() and all resources are loaded
-// first_paint: first paint performed
-// first_paint_after_load: first paint performed after load is finished
-// begin: request if it was user requested, start otherwise
-//
-// It's possible for the request time not to be set, if a client
-// redirect had been done (the user never requested the page)
-// Also, it's possible to load a page without ever laying it out
-// so first_paint and first_paint_after_load can be 0.
-void RenderView::DumpLoadHistograms() const {
- // Configuration for PLT related histograms.
- static const TimeDelta kPLTMin(TimeDelta::FromMilliseconds(10));
- static const TimeDelta kPLTMax(TimeDelta::FromMinutes(10));
- static const size_t kPLTCount(100);
- #define PLT_HISTOGRAM(name, sample) \
- UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, kPLTMin, kPLTMax, kPLTCount);
-
- WebFrame* main_frame = webview()->mainFrame();
- NavigationState* navigation_state =
- NavigationState::FromDataSource(main_frame->dataSource());
-
- URLPattern::SchemeMasks scheme_type = navigation_state->scheme_type();
- if (scheme_type == 0)
- return;
- DCHECK(scheme_type == URLPattern::SCHEME_HTTP ||
- scheme_type == URLPattern::SCHEME_HTTPS);
-
- // If we've already dumped, do nothing.
- if (navigation_state->load_histograms_recorded())
- return;
-
- // Collect measurement times.
- Time start = navigation_state->start_load_time();
- if (start.is_null())
- return; // Probably very premature abandonment of page.
- Time commit = navigation_state->commit_load_time();
- if (commit.is_null())
- return; // Probably very premature abandonment of page.
-
- // We properly handle null values for the next 3 variables.
- Time request = navigation_state->request_time();
- Time first_paint = navigation_state->first_paint_time();
- Time first_paint_after_load = navigation_state->first_paint_after_load_time();
- Time finish_doc = navigation_state->finish_document_load_time();
- Time finish_all_loads = navigation_state->finish_load_time();
-
- // Handle case where user hits "stop" or "back" before loading completely.
- bool abandoned_page = finish_doc.is_null();
- if (abandoned_page) {
- finish_doc = Time::Now();
- navigation_state->set_finish_document_load_time(finish_doc);
- }
-
- // TODO(jar): We should really discriminate the definition of "abandon" more
- // finely. We should have:
- // abandon_before_document_loaded
- // abandon_before_onload_fired
-
- if (finish_all_loads.is_null()) {
- finish_all_loads = Time::Now();
- navigation_state->set_finish_load_time(finish_all_loads);
- } else {
- DCHECK(!abandoned_page); // How can the doc have finished but not the page?
- if (!abandoned_page)
- return; // Don't try to record a stat which is broken.
- }
-
- // Note: Client side redirects will have no request time.
- 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;
-
- NavigationState::LoadType load_type = navigation_state->load_type();
-
- // The above code sanitized all values of times, in preparation for creating
- // actual histograms. The remainder of this code could be run at destructor
- // time for the navigation_state, since all data is intact.
-
- // Aggregate PLT data across all link types.
- UMA_HISTOGRAM_ENUMERATION("PLT.Abandoned", abandoned_page ? 1 : 0, 2);
- UMA_HISTOGRAM_ENUMERATION("PLT.LoadType", load_type,
- NavigationState::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()) {
- DCHECK(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()) {
- DCHECK(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);
-
- // Load type related histograms.
- switch (load_type) {
- case NavigationState::UNDEFINED_LOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_UndefLoad", begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_UndefLoad", begin_to_finish_all_loads);
- break;
- case NavigationState::RELOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_Reload", begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_Reload", begin_to_finish_all_loads);
- break;
- case NavigationState::HISTORY_LOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_HistoryLoad", begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_HistoryLoad", begin_to_finish_all_loads);
- break;
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_NormalLoad", begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_NormalLoad", begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadNormal",
- begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadNormal",
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM("PLT.BeginToFinishDoc_LinkLoadReload",
- begin_to_finish_doc);
- PLT_HISTOGRAM("PLT.BeginToFinish_LinkLoadReload",
- begin_to_finish_all_loads);
- break;
- case NavigationState::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 NavigationState::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;
- }
-
- // Histograms to determine if DNS prefetching has an impact on PLT.
- static bool use_dns_histogram(base::FieldTrialList::Find("DnsImpact") &&
- !base::FieldTrialList::Find("DnsImpact")->group_name().empty());
- 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, NavigationState::kLoadTypeMax);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "DnsImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "DnsImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "DnsImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "DnsImpact"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine if content prefetching has an impact on PLT.
- static const bool prefetching_fieldtrial =
- base::FieldTrialList::Find("Prefetch") &&
- !base::FieldTrialList::Find("Prefetch")->group_name().empty();
- if (prefetching_fieldtrial) {
- if (navigation_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 (navigation_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);
- }
-
- // Histograms to determine if backup connection jobs have an impact on PLT.
- static const bool connect_backup_jobs_fieldtrial(
- base::FieldTrialList::Find("ConnnectBackupJobs") &&
- !base::FieldTrialList::Find("ConnnectBackupJobs")->group_name().empty());
- 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, NavigationState::kLoadTypeMax);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "ConnnectBackupJobs"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "ConnnectBackupJobs"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "ConnnectBackupJobs"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "ConnnectBackupJobs"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine if the number of connections has an
- // impact on PLT.
- // TODO(jar): Consider removing the per-link-type versions. We
- // really only need LINK_LOAD_NORMAL and NORMAL_LOAD.
- static bool use_connection_impact_histogram(
- base::FieldTrialList::Find("ConnCountImpact") &&
- !base::FieldTrialList::Find("ConnCountImpact")->group_name().empty());
- if (use_connection_impact_histogram) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.Abandoned", "ConnCountImpact"),
- abandoned_page ? 1 : 0, 2);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "ConnCountImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "ConnCountImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "ConnCountImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "ConnCountImpact"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine effect of idle socket timeout.
- static bool use_idle_socket_timeout_histogram(
- base::FieldTrialList::Find("IdleSktToImpact") &&
- !base::FieldTrialList::Find("IdleSktToImpact")->group_name().empty());
- if (use_idle_socket_timeout_histogram) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.Abandoned", "IdleSktToImpact"),
- abandoned_page ? 1 : 0, 2);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "IdleSktToImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "IdleSktToImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "IdleSktToImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "IdleSktToImpact"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine effect of number of connections per proxy.
- static bool use_proxy_connection_impact_histogram(
- base::FieldTrialList::Find("ProxyConnectionImpact") &&
- !base::FieldTrialList::Find("ProxyConnectionImpact")->
- group_name().empty());
- if (use_proxy_connection_impact_histogram) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.Abandoned", "ProxyConnectionImpact"),
- abandoned_page ? 1 : 0, 2);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "ProxyConnectionImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "ProxyConnectionImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "ProxyConnectionImpact"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "ProxyConnectionImpact"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine if SDCH has an impact.
- // TODO(jar): Consider removing per-link load types and the enumeration.
- static bool use_sdch_histogram(base::FieldTrialList::Find("GlobalSdch") &&
- !base::FieldTrialList::Find("GlobalSdch")->group_name().empty());
- if (use_sdch_histogram) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.LoadType", "GlobalSdch"),
- load_type, NavigationState::kLoadTypeMax);
- switch (load_type) {
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "GlobalSdch"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "GlobalSdch"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "GlobalSdch"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "GlobalSdch"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_ONLY:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadCacheOnly", "GlobalSdch"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- }
-
- // Histograms to determine if cache size has an impact on PLT.
- static bool use_cache_histogram1(base::FieldTrialList::Find("CacheSize") &&
- !base::FieldTrialList::Find("CacheSize")->group_name().empty());
- if (use_cache_histogram1 &&
- NavigationState::LINK_LOAD_NORMAL <= load_type &&
- NavigationState::LINK_LOAD_CACHE_ONLY >= load_type) {
- // TODO(mbelshe): Do we really want BeginToFinishDoc here? It seems like
- // StartToFinish or BeginToFinish would be better.
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinishDoc_LinkLoad", "CacheSize"), begin_to_finish_doc);
- }
-
- // Histograms to determine if cache throttling has an impact on PLT.
- static bool use_cache_histogram2(
- base::FieldTrialList::Find("CacheThrottle") &&
- !base::FieldTrialList::Find("CacheThrottle")->group_name().empty());
- if (use_cache_histogram2) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.Abandoned", "CacheThrottle"),
- abandoned_page ? 1 : 0, 2);
- switch (load_type) {
- case NavigationState::RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_Reload", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::HISTORY_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_HistoryLoad", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_RELOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadReload", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_STALE_OK:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadStaleOk", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- case NavigationState::LINK_LOAD_CACHE_ONLY:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadCacheOnly", "CacheThrottle"),
- begin_to_finish_all_loads);
- break;
- default:
- break;
- }
- if (NavigationState::RELOAD <= load_type &&
- NavigationState::LINK_LOAD_CACHE_ONLY >= load_type) {
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish", "CacheThrottle"),
- begin_to_finish_all_loads);
- }
- }
-
- // For the SPDY field trials, we need to verify that the page loaded was
- // the type we requested:
- // if we asked for a SPDY request, we got a SPDY request
- // if we asked for a HTTP request, we got a HTTP request
- // Due to spdy version mismatches, it is possible that we ask for SPDY
- // but didn't get SPDY.
- static bool use_spdy_histogram(base::FieldTrialList::Find("SpdyImpact") &&
- !base::FieldTrialList::Find("SpdyImpact")->group_name().empty());
- if (use_spdy_histogram) {
- // We take extra effort to only compute these once.
- 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 = navigation_state->was_fetched_via_spdy() ?
- in_spdy_trial : in_http_trial;
- if (spdy_trial_success) {
- // Histograms to determine if SPDY has an impact for https traffic.
- // TODO(mbelshe): After we've seen the difference between BeginToFinish
- // and StartToFinish, consider removing one or the other.
- if (scheme_type == URLPattern::SCHEME_HTTPS &&
- navigation_state->was_npn_negotiated()) {
- UMA_HISTOGRAM_ENUMERATION(
- base::FieldTrial::MakeName("PLT.Abandoned", "SpdyImpact"),
- abandoned_page ? 1 : 0, 2);
- switch (load_type) {
- case NavigationState::LINK_LOAD_NORMAL:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
- begin_to_finish_all_loads);
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.StartToFinish_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
- start_to_finish_all_loads);
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.StartToCommit_LinkLoadNormal_SpdyTrial", "SpdyImpact"),
- start_to_commit);
- break;
- case NavigationState::NORMAL_LOAD:
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.BeginToFinish_NormalLoad_SpdyTrial", "SpdyImpact"),
- begin_to_finish_all_loads);
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.StartToFinish_NormalLoad_SpdyTrial", "SpdyImpact"),
- start_to_finish_all_loads);
- PLT_HISTOGRAM(base::FieldTrial::MakeName(
- "PLT.StartToCommit_NormalLoad_SpdyTrial", "SpdyImpact"),
- start_to_commit);
- break;
- default:
- break;
- }
- }
-
- // Histograms to compare the impact of alternate protocol over http
- // traffic: when spdy is used vs. when http is used.
- if (scheme_type == URLPattern::SCHEME_HTTP &&
- navigation_state->was_alternate_protocol_available()) {
- if (!navigation_state->was_npn_negotiated()) {
- // This means that even there is alternate protocols for npn_http or
- // npn_spdy, they are not taken (due to the base::FieldTrial).
- switch (load_type) {
- case NavigationState::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 NavigationState::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 (navigation_state->was_fetched_via_spdy()) {
- switch (load_type) {
- case NavigationState::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 NavigationState::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;
- }
- }
- }
- }
- }
-
- // Record page load time and abandonment rates for proxy cases.
- if (navigation_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);
- }
- }
-
- // Site isolation metrics.
- UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithCrossSiteFrameAccess",
- cross_origin_access_count_);
- UMA_HISTOGRAM_COUNTS("SiteIsolation.PageLoadsWithSameSiteFrameAccess",
- same_origin_access_count_);
-
- // TODO(jar): This is the ONLY call in this method that needed more than
- // navigation_state. This should be relocated, or changed, so that this
- // body can be made a method on NavigationStates, and run via its destructor.
- // Log some PLT data to the error log.
- LogNavigationState(navigation_state, main_frame->dataSource());
-
- navigation_state->set_load_histograms_recorded(true);
-
- // Since there are currently no guarantees that renderer histograms will be
- // sent to the browser, we initiate a PostTask here to be sure that we send
- // the histograms we generated. Without this call, pages that don't have an
- // on-close-handler might generate data that is lost when the renderer is
- // shutdown abruptly (perchance because the user closed the tab).
- // TODO(jar) BUG=33233: This needs to be moved to a PostDelayedTask, and it
- // should post when the onload is complete, so that it doesn't interfere with
- // the next load.
- if (RenderThread::current()) {
- RenderThread::current()->SendHistograms(
- chrome::kHistogramSynchronizerReservedSequenceNumber);
- }
-}
-
-void RenderView::LogNavigationState(const NavigationState* state,
- const WebDataSource* ds) const {
- // Because this function gets called on every page load,
- // take extra care to optimize it away if logging is turned off.
- if (logging::LOG_INFO < logging::GetMinLogLevel())
- return;
-
- DCHECK(state);
- DCHECK(ds);
- GURL url(ds->request().url());
- Time start = state->start_load_time();
- Time finish = state->finish_load_time();
- // TODO(mbelshe): should we log more stats?
- VLOG(1) << "PLT: " << (finish - start).InMilliseconds() << "ms "
- << url.spec();
-}
-
void RenderView::postAccessibilityNotification(
const WebAccessibilityObject& obj,
WebAccessibilityNotification notification) {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index cd28c02..321faf0 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -28,6 +28,7 @@
#include "chrome/common/render_messages_params.h"
#include "chrome/common/renderer_preferences.h"
#include "chrome/common/view_types.h"
+#include "chrome/renderer/page_load_histograms.h"
#include "chrome/renderer/pepper_plugin_delegate_impl.h"
#include "chrome/renderer/render_widget.h"
#include "chrome/renderer/renderer_webcookiejar_impl.h"
@@ -960,8 +961,6 @@ class RenderView : public RenderWidget,
// image doesn't have a frame at the specified size, the first is returned.
bool DownloadImage(int id, const GURL& image_url, int image_size);
- void DumpLoadHistograms() const;
-
// Initializes the document_tag_ member if necessary.
void EnsureDocumentTag();
@@ -1011,10 +1010,6 @@ class RenderView : public RenderWidget,
const std::string& html,
bool replace);
- // Logs the navigation state to the console.
- void LogNavigationState(const NavigationState* state,
- const WebKit::WebDataSource* ds) const;
-
bool MaybeLoadAlternateErrorPage(WebKit::WebFrame* frame,
const WebKit::WebURLError& error,
bool replace);
@@ -1174,11 +1169,6 @@ class RenderView : public RenderWidget,
int document_tag_;
- // Site isolation metrics flags. These are per-page-load counts, reset to 0
- // in OnClosePage.
- int cross_origin_access_count_;
- int same_origin_access_count_;
-
// UI state ------------------------------------------------------------------
// The state of our target_url transmissions. When we receive a request to
@@ -1319,6 +1309,9 @@ class RenderView : public RenderWidget,
// Device orientation dispatcher attached to this view; lazily initialized.
scoped_ptr<DeviceOrientationDispatcher> device_orientation_dispatcher_;
+ // Responsible for sending page load related histograms.
+ PageLoadHistograms page_load_histograms_;
+
// Misc ----------------------------------------------------------------------
// The current and pending file chooser completion objects. If the queue is