diff options
-rw-r--r-- | chrome/browser/browser_main.cc | 23 | ||||
-rw-r--r-- | chrome/browser/browser_main.h | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 2 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.cc | 15 | ||||
-rw-r--r-- | chrome/browser/renderer_host/resource_dispatcher_host.h | 7 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 22 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 5 | ||||
-rw-r--r-- | chrome/renderer/navigation_state.h | 18 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 99 |
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 |