Commit 66b83d54 authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

IsolatedPrerender: Add param to control which positions are prefetched

This CL adds an optional experiment param that controls what positions
of the navigation prediction can be prefetched if they are eligible.
In practice, this will hopefully control the number of prefetches that
occur on searches where the first eligible link is pretty far down the
page.

The param is a CSV instead of a min/max to allow fine-grained control.

Bug: 1141988
Change-Id: I35d581e10c291f6aaca79370c9f8f23aca76e40d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2495965Reviewed-by: default avatarRyan Sturm <ryansturm@chromium.org>
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821340}
parent 7842aa17
......@@ -5,11 +5,14 @@
#include "chrome/browser/prerender/isolated/isolated_prerender_params.h"
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_features.h"
#include "chrome/common/chrome_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
......@@ -198,3 +201,18 @@ bool IsolatedPrerenderStartsSpareRenderer() {
base::GetFieldTrialParamByFeatureAsBool(features::kIsolatePrerenders,
"start_spare_renderer", false);
}
bool IsolatedPrerenderShouldPrefetchPosition(size_t position) {
std::string csv = base::GetFieldTrialParamValueByFeature(
features::kIsolatePrerenders, "prefetch_positions");
if (csv.empty()) {
return true;
}
// Using a static set that is parsed from |csv| causes tests to fail when the
// tests share the same process. This approach is faster than having to parse
// each value as a number then check for contains.
return base::Contains(base::SplitString(csv, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY),
base::NumberToString(position));
}
......@@ -86,4 +86,7 @@ size_t IsolatedPrerenderMaxSubresourcesPerPrerender();
// complete.
bool IsolatedPrerenderStartsSpareRenderer();
// Whether the given position of a predicted link should be prefetched.
bool IsolatedPrerenderShouldPrefetchPosition(size_t position);
#endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PARAMS_H_
// Copyright 2020 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/browser/prerender/isolated/isolated_prerender_params.h"
#include <vector>
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_features.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(IsolatedPrerenderParamsTest, PrefetchPosition_DefaultEmpty) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"prefetch_positions", ""}});
for (size_t want_position :
std::vector<size_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) {
SCOPED_TRACE(want_position);
EXPECT_TRUE(IsolatedPrerenderShouldPrefetchPosition(want_position));
}
}
TEST(IsolatedPrerenderParamsTest, PrefetchPosition_SingleIndex) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"prefetch_positions", "0"}});
EXPECT_TRUE(IsolatedPrerenderShouldPrefetchPosition(0));
for (size_t not_want_position :
std::vector<size_t>{1, 2, 3, 4, 5, 6, 7, 8, 9}) {
SCOPED_TRACE(not_want_position);
EXPECT_FALSE(IsolatedPrerenderShouldPrefetchPosition(not_want_position));
}
}
TEST(IsolatedPrerenderParamsTest, PrefetchPosition_Normal) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"prefetch_positions", "0,1,2"}});
for (size_t want_position : std::vector<size_t>{0, 1, 2}) {
SCOPED_TRACE(want_position);
EXPECT_TRUE(IsolatedPrerenderShouldPrefetchPosition(want_position));
}
for (size_t not_want_position : std::vector<size_t>{3, 4, 5, 6, 7, 8, 9}) {
SCOPED_TRACE(not_want_position);
EXPECT_FALSE(IsolatedPrerenderShouldPrefetchPosition(not_want_position));
}
}
TEST(IsolatedPrerenderParamsTest, PrefetchPosition_Messy) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders,
{{"prefetch_positions", " 2,3, invalid, 5,,7"}});
for (size_t want_position : std::vector<size_t>{2, 3, 5, 7}) {
SCOPED_TRACE(want_position);
EXPECT_TRUE(IsolatedPrerenderShouldPrefetchPosition(want_position));
}
for (size_t not_want_position : std::vector<size_t>{0, 1, 4, 6, 8, 9}) {
SCOPED_TRACE(not_want_position);
EXPECT_FALSE(IsolatedPrerenderShouldPrefetchPosition(not_want_position));
}
}
......@@ -89,6 +89,10 @@ enum class IsolatedPrerenderPrefetchStatus {
// A subresource which was not fetched because it was throttled by an
// experimental control for the max number of subresources per prerender.
kSubresourceThrottled = 25,
// The position of the link in the navigation prediction was not eligible to
// be prefetch due to experiment controls.
kPrefetchPositionIneligible = 26,
};
#endif // CHROME_BROWSER_PRERENDER_ISOLATED_ISOLATED_PRERENDER_PREFETCH_STATUS_H_
......@@ -393,6 +393,7 @@ IsolatedPrerenderTabHelper::MaybeUpdatePrefetchStatusWithNSPContext(
case IsolatedPrerenderPrefetchStatus::kPrefetchSuccessful:
case IsolatedPrerenderPrefetchStatus::kNavigatedToLinkNotOnSRP:
case IsolatedPrerenderPrefetchStatus::kSubresourceThrottled:
case IsolatedPrerenderPrefetchStatus::kPrefetchPositionIneligible:
return status;
// These statuses we are going to update to, and this is the only place that
// they are set so they are not expected to be passed in.
......@@ -1254,6 +1255,12 @@ void IsolatedPrerenderTabHelper::OnGotEligibilityResult(
page_->srp_metrics_->ordered_eligible_pages_bitmask_ |=
1 << original_prediction_index;
}
if (!IsolatedPrerenderShouldPrefetchPosition(original_prediction_index)) {
OnPrefetchStatusUpdate(
url, IsolatedPrerenderPrefetchStatus::kPrefetchPositionIneligible);
return;
}
}
Prefetch();
......
......@@ -918,6 +918,34 @@ TEST_F(IsolatedPrerenderTabHelperTest, NonHTML) {
"IsolatedPrerender.Prefetch.Mainframe.TotalRedirects", 0, 1);
}
TEST_F(IsolatedPrerenderTabHelperTest, EligiblePredictionPositions) {
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"prefetch_positions", "0"}});
NavigateSomewhere();
GURL doc_url("https://www.google.com/search?q=cats");
GURL ineligible_url("http://www.meow.com/");
GURL eligible_url("https://www.cat-food.com/");
MakeNavigationPrediction(web_contents(), doc_url,
{ineligible_url, eligible_url});
EXPECT_EQ(RequestCount(), 0);
EXPECT_EQ(predicted_urls_count(), 2U);
EXPECT_EQ(prefetch_eligible_count(), 1U);
EXPECT_EQ(prefetch_attempted_count(), 0U);
EXPECT_EQ(prefetch_successful_count(), 0U);
EXPECT_EQ(prefetch_total_redirect_count(), 0U);
EXPECT_FALSE(navigation_to_prefetch_start().has_value());
NavigateAndVerifyPrefetchStatus(
eligible_url,
IsolatedPrerenderPrefetchStatus::kPrefetchPositionIneligible);
EXPECT_EQ(after_srp_prefetch_eligible_count(), 1U);
EXPECT_EQ(base::Optional<size_t>(1), after_srp_clicked_link_srp_position());
}
TEST_F(IsolatedPrerenderTabHelperTest, UserSettingDisabled) {
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_feature_list;
......
......@@ -3601,6 +3601,7 @@ test("unit_tests") {
"../browser/prefs/profile_pref_store_manager_unittest.cc",
"../browser/prefs/proxy_policy_unittest.cc",
"../browser/prefs/session_startup_pref_unittest.cc",
"../browser/prerender/isolated/isolated_prerender_params_unittest.cc",
"../browser/prerender/isolated/isolated_prerender_prefetch_metrics_collector_unittest.cc",
"../browser/prerender/isolated/isolated_prerender_proxy_configurator_unittest.cc",
"../browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc",
......
......@@ -39270,6 +39270,7 @@ Called by update_gpu_driver_bug_workaround_entries.py.-->
and the origin probe failed and the prefetch was not used.
</int>
<int value="25" label="Subresource throttled"/>
<int value="26" label="Prediction position not eligible"/>
</enum>
<enum name="IsPinnedToTaskbarResult">
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