Commit 33fee988 authored by Ryan Sturm's avatar Ryan Sturm Committed by Commit Bot

Add an experiment to move preconnect same origin to commit

Currently, we are blocked on Load Event, but we should move to x seconds
after commit instead.

Bug: 1016553
Change-Id: Ic1ec95fd543e0b50a4541a7d860b1ce40baae2d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1872423
Commit-Queue: Ryan Sturm <ryansturm@chromium.org>
Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Reviewed-by: default avatarRobert Ogden <robertogden@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708388}
parent 4e642edc
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/bind.h" #include "base/bind.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -33,11 +34,16 @@ const base::Feature kNavigationPredictorPreconnectHoldback { ...@@ -33,11 +34,16 @@ const base::Feature kNavigationPredictorPreconnectHoldback {
#endif #endif
}; };
// Experiment with which event triggers the preconnect after commit.
const base::Feature kPreconnectOnDidFinishNavigation{
"PreconnectOnDidFinishNavigation", base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace } // namespace
NavigationPredictorPreconnectClient::NavigationPredictorPreconnectClient( NavigationPredictorPreconnectClient::NavigationPredictorPreconnectClient(
content::WebContents* web_contents) content::WebContents* web_contents)
: browser_context_(web_contents->GetBrowserContext()), : content::WebContentsObserver(web_contents),
browser_context_(web_contents->GetBrowserContext()),
current_visibility_(web_contents->GetVisibility()) {} current_visibility_(web_contents->GetVisibility()) {}
NavigationPredictorPreconnectClient::~NavigationPredictorPreconnectClient() = NavigationPredictorPreconnectClient::~NavigationPredictorPreconnectClient() =
...@@ -51,6 +57,20 @@ void NavigationPredictorPreconnectClient::DidFinishNavigation( ...@@ -51,6 +57,20 @@ void NavigationPredictorPreconnectClient::DidFinishNavigation(
// New page, so stop the preconnect timer. // New page, so stop the preconnect timer.
timer_.Stop(); timer_.Stop();
if (base::FeatureList::IsEnabled(kPreconnectOnDidFinishNavigation)) {
int delay_ms = base::GetFieldTrialParamByFeatureAsInt(
kPreconnectOnDidFinishNavigation, "delay_after_commit_in_ms", 3000);
if (delay_ms <= 0) {
MaybePreconnectNow();
return;
}
timer_.Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms),
base::BindOnce(&NavigationPredictorPreconnectClient::MaybePreconnectNow,
base::Unretained(this)));
}
} }
void NavigationPredictorPreconnectClient::OnVisibilityChanged( void NavigationPredictorPreconnectClient::OnVisibilityChanged(
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/metrics/subprocess_metrics_provider.h" #include "chrome/browser/predictors/loading_predictor.h"
#include "chrome/browser/predictors/loading_predictor_factory.h"
#include "chrome/browser/predictors/preconnect_manager.h"
#include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h" #include "chrome/browser/subresource_filter/subresource_filter_browser_test_harness.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
...@@ -24,7 +25,8 @@ ...@@ -24,7 +25,8 @@
namespace { namespace {
class NavigationPredictorPreconnectClientBrowserTest class NavigationPredictorPreconnectClientBrowserTest
: public subresource_filter::SubresourceFilterBrowserTest { : public subresource_filter::SubresourceFilterBrowserTest,
public predictors::PreconnectManager::Observer {
public: public:
NavigationPredictorPreconnectClientBrowserTest() NavigationPredictorPreconnectClientBrowserTest()
: subresource_filter::SubresourceFilterBrowserTest() { : subresource_filter::SubresourceFilterBrowserTest() {
...@@ -45,36 +47,40 @@ class NavigationPredictorPreconnectClientBrowserTest ...@@ -45,36 +47,40 @@ class NavigationPredictorPreconnectClientBrowserTest
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
subresource_filter::SubresourceFilterBrowserTest::SetUpOnMainThread(); subresource_filter::SubresourceFilterBrowserTest::SetUpOnMainThread();
host_resolver()->ClearRules(); host_resolver()->ClearRules();
auto* loading_predictor =
predictors::LoadingPredictorFactory::GetForProfile(
browser()->profile());
ASSERT_TRUE(loading_predictor);
loading_predictor->preconnect_manager()->SetObserverForTesting(this);
} }
const GURL GetTestURL(const char* file) const { const GURL GetTestURL(const char* file) const {
return https_server_->GetURL(file); return https_server_->GetURL(file);
} }
// Retries fetching |histogram_name| until it contains at least |count| void OnPreresolveFinished(const GURL& url, bool success) override {
// samples. EXPECT_TRUE(success);
void RetryForHistogramUntilCountReached( preresolve_done_count_++;
const base::HistogramTester& histogram_tester, if (run_loop_)
const std::string& histogram_name, run_loop_->Quit();
size_t count) { }
base::RunLoop().RunUntilIdle();
for (size_t attempt = 0; attempt < 50; ++attempt) { void WaitForPreresolveCount(int expected_count) {
const std::vector<base::Bucket> buckets = while (preresolve_done_count_ < expected_count) {
histogram_tester.GetAllSamples(histogram_name); run_loop_ = std::make_unique<base::RunLoop>();
size_t total_count = 0; run_loop_->Run();
for (const auto& bucket : buckets) run_loop_.reset();
total_count += bucket.count;
if (total_count >= count)
return;
content::FetchHistogramsFromChildProcesses();
SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
base::RunLoop().RunUntilIdle();
} }
} }
protected:
int preresolve_done_count_ = 0;
private: private:
std::unique_ptr<net::EmbeddedTestServer> https_server_; std::unique_ptr<net::EmbeddedTestServer> https_server_;
base::test::ScopedFeatureList feature_list_; base::test::ScopedFeatureList feature_list_;
std::unique_ptr<base::RunLoop> run_loop_;
DISALLOW_COPY_AND_ASSIGN(NavigationPredictorPreconnectClientBrowserTest); DISALLOW_COPY_AND_ASSIGN(NavigationPredictorPreconnectClientBrowserTest);
}; };
...@@ -100,26 +106,20 @@ IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, ...@@ -100,26 +106,20 @@ IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest,
model->SetUserSelectedDefaultSearchProvider(template_url); model->SetUserSelectedDefaultSearchProvider(template_url);
const GURL& url = GetTestURL("/anchors_different_area.html?q=cats"); const GURL& url = GetTestURL("/anchors_different_area.html?q=cats");
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
// There should be preconnect from navigation, but not preconnect client. // There should be preconnect from navigation, but not preconnect client.
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); EXPECT_EQ(1, preresolve_done_count_);
ui_test_utils::NavigateToURL(browser(), url);
// There should be 2 preconnects from navigation, but not any from preconnect
// client.
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 2);
} }
IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest,
PreconnectNotSearch) { PreconnectNotSearch) {
const GURL& url = GetTestURL("/anchors_different_area.html"); const GURL& url = GetTestURL("/anchors_different_area.html");
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
// There should be preconnect from navigation and one from preconnect client. // There should be one preconnect from navigation and one from preconnect
RetryForHistogramUntilCountReached(histogram_tester, // client.
"LoadingPredictor.PreconnectCount", 2); WaitForPreresolveCount(2);
EXPECT_EQ(2, preresolve_done_count_);
} }
IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest,
...@@ -127,26 +127,26 @@ IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest, ...@@ -127,26 +127,26 @@ IN_PROC_BROWSER_TEST_F(NavigationPredictorPreconnectClientBrowserTest,
const GURL& url = GetTestURL("/anchors_different_area.html"); const GURL& url = GetTestURL("/anchors_different_area.html");
browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); browser()->tab_strip_model()->GetActiveWebContents()->WasHidden();
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
// There should be a navigational preconnect. // There should be a navigational preconnect.
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); EXPECT_EQ(1, preresolve_done_count_);
// Change to visible. // Change to visible.
browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); browser()->tab_strip_model()->GetActiveWebContents()->WasShown();
// After showing the contents, there should be a preconnect client preconnect. // After showing the contents, there should be a preconnect client preconnect.
RetryForHistogramUntilCountReached(histogram_tester, WaitForPreresolveCount(2);
"LoadingPredictor.PreconnectCount", 2); EXPECT_EQ(2, preresolve_done_count_);
browser()->tab_strip_model()->GetActiveWebContents()->WasHidden(); browser()->tab_strip_model()->GetActiveWebContents()->WasHidden();
browser()->tab_strip_model()->GetActiveWebContents()->WasShown(); browser()->tab_strip_model()->GetActiveWebContents()->WasShown();
// After showing the contents again, there should be another preconnect client // After showing the contents again, there should be another preconnect client
// preconnect. // preconnect.
RetryForHistogramUntilCountReached(histogram_tester, WaitForPreresolveCount(3);
"LoadingPredictor.PreconnectCount", 3); EXPECT_EQ(3, preresolve_done_count_);
} }
class NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout class NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout
...@@ -167,12 +167,16 @@ class NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout ...@@ -167,12 +167,16 @@ class NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout
IN_PROC_BROWSER_TEST_F( IN_PROC_BROWSER_TEST_F(
NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout, NavigationPredictorPreconnectClientBrowserTestWithUnusedIdleSocketTimeout,
ActionAccuracy_timeout) { ActionAccuracy_timeout) {
base::HistogramTester histogram_tester;
const GURL& url = GetTestURL("/page_with_same_host_anchor_element.html"); const GURL& url = GetTestURL("/page_with_same_host_anchor_element.html");
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); WaitForPreresolveCount(3);
EXPECT_EQ(3, preresolve_done_count_);
// Expect another one.
WaitForPreresolveCount(4);
EXPECT_EQ(4, preresolve_done_count_);
} }
class NavigationPredictorPreconnectClientBrowserTestWithHoldback class NavigationPredictorPreconnectClientBrowserTestWithHoldback
...@@ -193,15 +197,69 @@ IN_PROC_BROWSER_TEST_F( ...@@ -193,15 +197,69 @@ IN_PROC_BROWSER_TEST_F(
NoPreconnectHoldback) { NoPreconnectHoldback) {
const GURL& url = GetTestURL("/anchors_different_area.html"); const GURL& url = GetTestURL("/anchors_different_area.html");
base::HistogramTester histogram_tester;
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
// There should be preconnect from navigation, but not preconnect client. // There should be preconnect from navigation, but not preconnect client.
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 1); EXPECT_EQ(1, preresolve_done_count_);
ui_test_utils::NavigateToURL(browser(), url); ui_test_utils::NavigateToURL(browser(), url);
// There should be 2 preconnects from navigation, but not any from preconnect // There should be 2 preconnects from navigation, but not any from preconnect
// client. // client.
histogram_tester.ExpectTotalCount("LoadingPredictor.PreconnectCount", 2); EXPECT_EQ(2, preresolve_done_count_);
}
const base::Feature kPreconnectOnDidFinishNavigation{
"PreconnectOnDidFinishNavigation", base::FEATURE_DISABLED_BY_DEFAULT};
class
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay
: public NavigationPredictorPreconnectClientBrowserTest {
public:
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay()
: NavigationPredictorPreconnectClientBrowserTest() {
feature_list_.InitAndEnableFeatureWithParameters(
kPreconnectOnDidFinishNavigation,
{{"delay_after_commit_in_ms", "1000"}});
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_F(
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationSecondDelay,
PreconnectNotSearch) {
const GURL& url = GetTestURL("/anchors_different_area.html");
ui_test_utils::NavigateToURL(browser(), url);
// There should be preconnect from navigation and one from OnLoad client.
WaitForPreresolveCount(2);
EXPECT_EQ(2, preresolve_done_count_);
}
class
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay
: public NavigationPredictorPreconnectClientBrowserTest {
public:
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay()
: NavigationPredictorPreconnectClientBrowserTest() {
feature_list_.InitAndEnableFeatureWithParameters(
kPreconnectOnDidFinishNavigation, {{"delay_after_commit_in_ms", "0"}});
}
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_F(
NavigationPredictorPreconnectClientBrowserTestPreconnectOnDidFinishNavigationNoDelay,
PreconnectNotSearch) {
const GURL& url = GetTestURL("/anchors_different_area.html");
ui_test_utils::NavigateToURL(browser(), url);
// There should be a navigation preconnect, a commit preconnect, and an OnLoad
// preconnect.
WaitForPreresolveCount(3);
EXPECT_EQ(3, preresolve_done_count_);
} }
} // namespace } // namespace
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment