summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_main.cc23
-rw-r--r--chrome/browser/browser_main.h3
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc2
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc15
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h7
-rw-r--r--chrome/common/chrome_switches.cc22
-rw-r--r--chrome/common/chrome_switches.h5
-rw-r--r--chrome/renderer/navigation_state.h18
-rw-r--r--chrome/renderer/render_view.cc99
9 files changed, 174 insertions, 20 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index cf806fc..5f8fa20 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -171,6 +171,7 @@ void BrowserMainParts::EarlyInitialization() {
SocketTimeoutFieldTrial();
ProxyConnectionsFieldTrial();
SpdyFieldTrial();
+ PrefetchFieldTrial();
InitializeSSL();
PostEarlyInitialization();
@@ -364,6 +365,28 @@ void BrowserMainParts::SpdyFieldTrial() {
}
}
+// If neither --enable-content-prefetch or --disable-content-prefetch
+// is set, users will be in an A/B test for prefetching.
+void BrowserMainParts::PrefetchFieldTrial() {
+ if (parsed_command_line().HasSwitch(switches::kEnableContentPrefetch))
+ ResourceDispatcherHost::set_is_prefetch_enabled(true);
+ else if (parsed_command_line().HasSwitch(switches::kDisableContentPrefetch)) {
+ ResourceDispatcherHost::set_is_prefetch_enabled(false);
+ } else {
+ const FieldTrial::Probability kPrefetchDivisor = 100;
+ const FieldTrial::Probability no_prefetch_probability = 90;
+ scoped_refptr<FieldTrial> trial =
+ new FieldTrial("Prefetch", kPrefetchDivisor);
+ trial->AppendGroup("ContentPrefetchDisabled", no_prefetch_probability);
+ const int yes_prefetch_grp =
+ trial->AppendGroup("ContentPrefetchEnabled",
+ FieldTrial::kAllRemainingProbability);
+ const int trial_grp = trial->group();
+ ResourceDispatcherHost::set_is_prefetch_enabled(
+ trial_grp == yes_prefetch_grp);
+ }
+}
+
// BrowserMainParts: |MainMessageLoopStart()| and related ----------------------
void BrowserMainParts::MainMessageLoopStart() {
diff --git a/chrome/browser/browser_main.h b/chrome/browser/browser_main.h
index 6ef2bbe..a632b966 100644
--- a/chrome/browser/browser_main.h
+++ b/chrome/browser/browser_main.h
@@ -113,6 +113,9 @@ class BrowserMainParts {
// A/B test for spdy when --use-spdy not set.
void SpdyFieldTrial();
+ // A/B test for prefetching with --(enable|disable)-prefetch not set.
+ void PrefetchFieldTrial();
+
// Used to initialize NSPR where appropriate.
virtual void InitializeSSL() = 0;
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index bee6232..a1ad2bc 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -578,6 +578,8 @@ void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer(
switches::kEnableRemoting,
switches::kEnableClickToPlay,
switches::kPrelaunchGpuProcess,
+ switches::kEnableContentPrefetch,
+ switches::kDisableContentPrefetch,
};
renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
arraysize(kSwitchNames));
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index bbdc32b..64ea651 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -126,7 +126,7 @@ bool ShouldServiceRequest(ChildProcessInfo::ProcessType process_type,
return true;
if (request_data.resource_type == ResourceType::PREFETCH &&
- !CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePrefetch))
+ !ResourceDispatcherHost::is_prefetch_enabled())
return false;
ChildProcessSecurityPolicy* policy =
@@ -1858,3 +1858,16 @@ net::RequestPriority ResourceDispatcherHost::DetermineRequestPriority(
return net::LOW;
}
}
+
+// static
+bool ResourceDispatcherHost::is_prefetch_enabled() {
+ return is_prefetch_enabled_;
+}
+
+// static
+void ResourceDispatcherHost::set_is_prefetch_enabled(bool value) {
+ is_prefetch_enabled_ = value;
+}
+
+// static
+bool ResourceDispatcherHost::is_prefetch_enabled_ = false;
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h
index dff1934..9583952 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.h
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.h
@@ -268,6 +268,11 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
// Needed for the sync IPC message dispatcher macros.
bool Send(IPC::Message* message);
+ // Controls if we launch or squash prefetch requests as they arrive
+ // from renderers.
+ static bool is_prefetch_enabled();
+ static void set_is_prefetch_enabled(bool value);
+
private:
FRIEND_TEST_ALL_PREFIXES(ResourceDispatcherHostTest,
TestBlockedRequestsProcessDies);
@@ -494,6 +499,8 @@ class ResourceDispatcherHost : public URLRequest::Delegate {
// to the source of the message.
Receiver* receiver_;
+ static bool is_prefetch_enabled_;
+
DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHost);
};
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 32cbdca..4df9c3c 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -129,6 +129,11 @@ const char kDisableBackingStoreLimit[] = "disable-backing-store-limit";
// Disable support for cached byte-ranges.
const char kDisableByteRangeSupport[] = "disable-byte-range-support";
+// Disable requests that webkit labels TargetIsPrefetch. As of
+// writing only <link rel=prefetch...> but also eventually
+// Link: headers.
+const char kDisableContentPrefetch[] = "disable-content-prefetch";
+
// Disables the custom JumpList on Windows 7.
const char kDisableCustomJumpList[] = "disable-custom-jumplist";
@@ -165,7 +170,7 @@ const char kDisableInternalFlash[] = "disable-internal-flash";
const char kDisableIPv6[] = "disable-ipv6";
// Disable speculative TCP/IP preconnection.
-const char kDisablePreconnect[] = "disable-preconnect";
+const char kDisablePreconnect[] = "disable-preconnect";
// Don't execute JavaScript (browser JS like the new tab page still runs).
const char kDisableJavaScript[] = "disable-javascript";
@@ -193,11 +198,6 @@ const char kDisablePlugins[] = "disable-plugins";
// Disable pop-up blocking.
const char kDisablePopupBlocking[] = "disable-popup-blocking";
-// Disable requests that webkit labels TargetIsPrefetch. As of
-// writing only <link rel=prefetch...> but also eventually
-// Link: headers.
-const char kDisablePrefetch[] = "disable-prefetch";
-
// Normally when the user attempts to navigate to a page that was the result of
// a post we prompt to make sure they want to. This switch may be used to
// disable that check. This switch is used during automated testing.
@@ -316,6 +316,11 @@ const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy";
// Enables the Cloud Print dialog hosting code.
const char kEnableCloudPrint[] = "enable-cloud-print";
+// Enable requests that webkit labels TargetIsPrefetch. As of
+// writing only <link rel=prefetch...> but also eventually
+// Link: headers.
+const char kEnableContentPrefetch[] = "enable-content-prefetch";
+
// Enables the cookie prompt.
const char kEnableCookiePrompt[] = "enable-cookie-prompt";
@@ -389,11 +394,6 @@ const char kEnableNativeWebWorkers[] = "enable-native-web-workers";
// Enable speculative TCP/IP preconnection.
const char kEnablePreconnect[] = "enable-preconnect";
-// Enable requests that webkit labels TargetIsPrefetch. As of
-// writing only <link rel=prefetch...> but also eventually
-// Link: headers.
-const char kEnablePrefetch[] = "enable-prefetch";
-
// Enable caching of pre-parsed JS script data. See http://crbug.com/32407.
const char kEnablePreparsedJsCaching[] = "enable-preparsed-js-caching";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 0db5f99..00385c3 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -51,6 +51,7 @@ extern const char kDisableAudio[];
extern const char kDisableAuthNegotiateCnameLookup[];
extern const char kDisableBackingStoreLimit[];
extern const char kDisableByteRangeSupport[];
+extern const char kDisableContentPrefetch[];
extern const char kDisableCustomJumpList[];
extern const char kDisableDatabases[];
extern const char kDisableDesktopNotifications[];
@@ -61,7 +62,6 @@ extern const char kDisableGeolocation[];
extern const char kDisableHangMonitor[];
extern const char kDisableInternalFlash[];
extern const char kDisableIPv6[];
-extern const char kDisablePreconnect[];
extern const char kDisableJavaScript[];
extern const char kDisableJava[];
extern const char kDisableLocalStorage[];
@@ -70,6 +70,7 @@ extern const char kDisableNewTabFirstRun[];
extern const char kDisableOutdatedPlugins[];
extern const char kDisablePlugins[];
extern const char kDisablePopupBlocking[];
+extern const char kDisablePreconnect[];
extern const char kDisablePromptOnRepost[];
extern const char kDisableRemoteFonts[];
extern const char kDisableRendererAccessibility[];
@@ -104,6 +105,7 @@ extern const char kEnableRemoting[];
extern const char kEnableClickToPlay[];
extern const char kEnableCloudPrintProxy[];
extern const char kEnableCloudPrint[];
+extern const char kEnableContentPrefetch[];
extern const char kEnableCookiePrompt[];
extern const char kEnableDeviceMotion[];
extern const char kEnableDeviceOrientation[];
@@ -125,7 +127,6 @@ extern const char kEnableMonitorProfile[];
extern const char kEnableNaCl[];
extern const char kEnableNativeWebWorkers[];
extern const char kEnablePreconnect[];
-extern const char kEnablePrefetch[];
extern const char kEnablePreparsedJsCaching[];
extern const char kEnablePrintPreview[];
extern const char kEnableSearchProviderApiV2[];
diff --git a/chrome/renderer/navigation_state.h b/chrome/renderer/navigation_state.h
index 7fa0505..afdebb8 100644
--- a/chrome/renderer/navigation_state.h
+++ b/chrome/renderer/navigation_state.h
@@ -240,6 +240,16 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
void set_was_translated(bool value) { was_translated_ = value; }
bool was_translated() const { return was_translated_; }
+ void set_was_prefetcher(bool value) { was_prefetcher_ = value; }
+ bool was_prefetcher() const { return was_prefetcher_; }
+
+ void set_was_referred_by_prefetcher(bool value) {
+ was_referred_by_prefetcher_ = value;
+ }
+ bool was_referred_by_prefetcher() const {
+ return was_referred_by_prefetcher_;
+ }
+
private:
NavigationState(PageTransition::Type transition_type,
const base::Time& request_time,
@@ -262,7 +272,9 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
was_npn_negotiated_(false),
was_alternate_protocol_available_(false),
was_fetched_via_proxy_(false),
- was_translated_(false) {
+ was_translated_(false),
+ was_prefetcher_(false),
+ was_referred_by_prefetcher_(false) {
}
PageTransition::Type transition_type_;
@@ -298,6 +310,10 @@ class NavigationState : public WebKit::WebDataSource::ExtraData {
bool was_fetched_via_proxy_;
bool was_translated_;
+ // A prefetcher is a page that contains link rel=prefetch elements.
+ bool was_prefetcher_;
+ bool was_referred_by_prefetcher_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationState);
};
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index bc400ef..e92fc2a 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -538,7 +538,7 @@ void RenderView::SetNextPageID(int32 next_page_id) {
next_page_id_ = next_page_id;
}
-WebKit::WebView* RenderView::webview() const{
+WebKit::WebView* RenderView::webview() const {
return static_cast<WebKit::WebView*>(webwidget());
}
@@ -2643,8 +2643,37 @@ void RenderView::didCreateDataSource(WebFrame* frame, WebDataSource* ds) {
NavigationState* state = content_initiated ?
NavigationState::CreateContentInitiated() :
pending_navigation_state_.release();
+
+ const WebURLRequest& original_request = ds->originalRequest();
+ const WebURLRequest& request = ds->request();
+
+ // NavigationState::referred_by_prefetcher_ is true if we are
+ // navigating from a page that used prefetching using a link on that
+ // page. We are early enough in the request process here that we
+ // can still see the NavigationState of the previous page and set
+ // this value appropriately.
+ // TODO(gavinp): catch the important case of navigation in a new
+ // renderer process.
+ if (webview()) {
+ if( WebFrame* old_frame = webview()->mainFrame()) {
+ const GURL referrer(
+ original_request.httpHeaderField(WebString::fromUTF8("Referer")));
+ if (!referrer.is_empty() &&
+ NavigationState::FromDataSource(
+ old_frame->dataSource())->was_prefetcher()) {
+ for (;old_frame;old_frame = old_frame->traverseNext(false)) {
+ WebDataSource* old_frame_ds = old_frame->dataSource();
+ if (old_frame_ds && referrer == GURL(old_frame_ds->request().url())) {
+ state->set_was_referred_by_prefetcher(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+
if (content_initiated) {
- switch (ds->request().cachePolicy()) {
+ switch (request.cachePolicy()) {
case WebURLRequest::UseProtocolCachePolicy: // normal load.
state->set_load_type(NavigationState::LINK_LOAD_NORMAL);
break;
@@ -3020,14 +3049,22 @@ void RenderView::willSendRequest(
WebFrame* top_frame = frame->top();
if (!top_frame)
top_frame = frame;
- WebDataSource* data_source = top_frame->provisionalDataSource();
- if (!data_source)
- data_source = top_frame->dataSource();
+ WebDataSource* provisional_data_source = top_frame->provisionalDataSource();
+ WebDataSource* top_data_source = top_frame->dataSource();
+ WebDataSource* data_source =
+ provisional_data_source ? provisional_data_source : top_data_source;
if (data_source) {
NavigationState* state = NavigationState::FromDataSource(data_source);
if (state && state->is_cache_policy_override_set())
request.setCachePolicy(state->cache_policy_override());
}
+
+ if (top_data_source) {
+ NavigationState* state = NavigationState::FromDataSource(top_data_source);
+ if (state && request.targetType() == WebURLRequest::TargetIsPrefetch)
+ state->set_was_prefetcher(true);
+ }
+
request.setRequestorID(routing_id_);
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoReferrers))
request.clearHTTPHeaderField("Referer");
@@ -4707,6 +4744,58 @@ void RenderView::DumpLoadHistograms() const {
}
}
+ // Histograms to determine if content prefetching has an impact on PLT.
+ static const bool prefetching_fieldtrial =
+ FieldTrialList::Find("Prefetch") &&
+ !FieldTrialList::Find("Prefetch")->group_name().empty();
+ static const bool prefetching_explicitly_disabled =
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableContentPrefetch);
+ if (navigation_state->was_prefetcher()) {
+ if (!prefetching_explicitly_disabled) {
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_ContentPrefetcher",
+ begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_ContentPrefetcher",
+ begin_to_finish);
+ }
+ if (prefetching_fieldtrial) {
+ PLT_HISTOGRAM(
+ FieldTrial::MakeName("PLT.BeginToFinishDoc_ContentPrefetcher",
+ "Prefetch"),
+ begin_to_finish_doc);
+ PLT_HISTOGRAM(
+ FieldTrial::MakeName("PLT.BeginToFinish_ContentPrefetcher",
+ "Prefetch"),
+ begin_to_finish);
+ }
+ }
+ if (navigation_state->was_referred_by_prefetcher()) {
+ if (!prefetching_explicitly_disabled) {
+ PLT_HISTOGRAM("PLT.BeginToFinishDoc_ContentPrefetcherReferrer",
+ begin_to_finish_doc);
+ PLT_HISTOGRAM("PLT.BeginToFinish_ContentPrefetcherReferrer",
+ begin_to_finish);
+ }
+ if (prefetching_fieldtrial) {
+ PLT_HISTOGRAM(
+ FieldTrial::MakeName("PLT.BeginToFinishDoc_ContentPrefetcherReferrer",
+ "Prefetch"),
+ begin_to_finish_doc);
+ PLT_HISTOGRAM(
+ FieldTrial::MakeName("PLT.BeginToFinish_ContentPrefetcherReferrer",
+ "Prefetch"),
+ begin_to_finish);
+ }
+ }
+ if (prefetching_fieldtrial) {
+ UMA_HISTOGRAM_ENUMERATION(FieldTrial::MakeName("PLT.Abandoned", "Prefetch"),
+ abandoned_page ? 1 : 0, 2);
+ PLT_HISTOGRAM(FieldTrial::MakeName("PLT.BeginToFinishDoc", "Prefetch"),
+ begin_to_finish_doc);
+ PLT_HISTOGRAM(FieldTrial::MakeName("PLT.BeginToFinish", "Prefetch"),
+ begin_to_finish);
+ }
+
// Histograms to determine if the number of connections has an
// impact on PLT.
// TODO(jar): Consider removing the per-link-type versions. We