Prerender2Fallback: Disable BlockUntilHeadTimeout for prerender
In an experiment of Prerender2FallbackPrefetchSpecRules, we had a result that BlockUntilHeadTimeout might degrades prerender activation. This CL disables it and adds a feature parameter to control the behavior. For more details, see https://docs.google.com/document/d/1ZP7lYrtqZL9jC2xXieNY_UBMJL1sCrfmzTB8K6v4sD4/edit?resourcekey=0-fkbeQhkT3PhBb9FnnPgnZA&tab=t.wphan8fb23kr Fixed: 405288111 Change-Id: I2bd5902d21d59d1ff59f04c9ea5a1cb79df12e7c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6380014 Commit-Queue: Ken Okada <kenoss@chromium.org> Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org> Auto-Submit: Ken Okada <kenoss@chromium.org> Reviewed-by: Taiyo Mizuhashi <taiyo@chromium.org> Cr-Commit-Position: refs/heads/main@{#1437924}
This commit is contained in:
content/browser/preloading
@ -46,12 +46,14 @@ PrefetchMatchResolver::CandidateData::~CandidateData() = default;
|
||||
PrefetchMatchResolver::PrefetchMatchResolver(
|
||||
PrefetchContainer::Key navigated_key,
|
||||
PrefetchServiceWorkerState expected_service_worker_state,
|
||||
bool is_nav_prerender,
|
||||
base::WeakPtr<PrefetchService> prefetch_service,
|
||||
Callback callback)
|
||||
: navigated_key_(std::move(navigated_key)),
|
||||
expected_service_worker_state_(expected_service_worker_state),
|
||||
prefetch_service_(std::move(prefetch_service)),
|
||||
callback_(std::move(callback)) {
|
||||
callback_(std::move(callback)),
|
||||
is_nav_prerender_(is_nav_prerender) {
|
||||
switch (expected_service_worker_state_) {
|
||||
case PrefetchServiceWorkerState::kAllowed:
|
||||
NOTREACHED();
|
||||
@ -86,22 +88,21 @@ void PrefetchMatchResolver::FindPrefetch(
|
||||
TRACE_EVENT0("loading", "PrefetchMatchResolver::FindPrefetch");
|
||||
// See the comment of `self_`.
|
||||
auto prefetch_match_resolver = base::WrapUnique(new PrefetchMatchResolver(
|
||||
std::move(navigated_key), expected_service_worker_state,
|
||||
std::move(navigated_key), expected_service_worker_state, is_nav_prerender,
|
||||
prefetch_service.GetWeakPtr(), std::move(callback)));
|
||||
PrefetchMatchResolver& ref = *prefetch_match_resolver.get();
|
||||
ref.self_ = std::move(prefetch_match_resolver);
|
||||
|
||||
ref.FindPrefetchInternal(is_nav_prerender, prefetch_service,
|
||||
ref.FindPrefetchInternal(prefetch_service,
|
||||
std::move(serving_page_metrics_container));
|
||||
}
|
||||
|
||||
void PrefetchMatchResolver::FindPrefetchInternal(
|
||||
bool is_nav_prerender,
|
||||
PrefetchService& prefetch_service,
|
||||
base::WeakPtr<PrefetchServingPageMetricsContainer>
|
||||
serving_page_metrics_container) {
|
||||
auto [candidates, servable_states] = prefetch_service.CollectMatchCandidates(
|
||||
navigated_key_, is_nav_prerender,
|
||||
navigated_key_, is_nav_prerender_,
|
||||
std::move(serving_page_metrics_container));
|
||||
// Consume `candidates`.
|
||||
for (auto& prefetch_container : candidates) {
|
||||
@ -217,10 +218,10 @@ void PrefetchMatchResolver::StartWaitFor(
|
||||
CHECK(!candidate_data->timeout_timer);
|
||||
|
||||
// TODO(crbug.com/356552413): Merge
|
||||
// https://chromium-review.googlesource.com/c/chromium/src/+/5668924 and write
|
||||
// tests.
|
||||
base::TimeDelta timeout =
|
||||
PrefetchBlockUntilHeadTimeout(prefetch_container.GetPrefetchType());
|
||||
// https://chromium-review.googlesource.com/c/chromium/src/+/5668924 and
|
||||
// write tests.
|
||||
base::TimeDelta timeout = PrefetchBlockUntilHeadTimeout(
|
||||
prefetch_container.GetPrefetchType(), is_nav_prerender_);
|
||||
if (timeout.is_positive()) {
|
||||
candidate_data->timeout_timer = std::make_unique<base::OneShotTimer>();
|
||||
candidate_data->timeout_timer->Start(
|
||||
|
@ -79,7 +79,8 @@ class CONTENT_EXPORT PrefetchMatchResolver final
|
||||
explicit PrefetchMatchResolver(
|
||||
PrefetchContainer::Key navigated_key,
|
||||
PrefetchServiceWorkerState expected_service_worker_state,
|
||||
base::WeakPtr<PrefetchService>,
|
||||
bool is_nav_prerender,
|
||||
base::WeakPtr<PrefetchService> prefetch_service,
|
||||
Callback callback);
|
||||
|
||||
// Returns blocked duration. Returns null iff it's not blocked yet.
|
||||
@ -97,8 +98,7 @@ class CONTENT_EXPORT PrefetchMatchResolver final
|
||||
// - This implementation has timeout: `CandidateData::timeout_timer`.
|
||||
// - This implementation collects candidate prefetches first. So, it doesn't
|
||||
// handle prefetches started after this method started.
|
||||
void FindPrefetchInternal(bool is_nav_prerender,
|
||||
PrefetchService& prefetch_service,
|
||||
void FindPrefetchInternal(PrefetchService& prefetch_service,
|
||||
base::WeakPtr<PrefetchServingPageMetricsContainer>
|
||||
serving_page_metrics_container);
|
||||
// Each candidate `PrefetchContainer` proceeds to
|
||||
@ -148,6 +148,7 @@ class CONTENT_EXPORT PrefetchMatchResolver final
|
||||
const PrefetchServiceWorkerState expected_service_worker_state_;
|
||||
base::WeakPtr<PrefetchService> prefetch_service_;
|
||||
Callback callback_;
|
||||
const bool is_nav_prerender_;
|
||||
std::map<PrefetchContainer::Key, std::unique_ptr<CandidateData>> candidates_;
|
||||
std::optional<base::TimeTicks> wait_started_at_ = std::nullopt;
|
||||
};
|
||||
|
@ -188,8 +188,23 @@ int PrefetchCanaryCheckRetries() {
|
||||
features::kPrefetchUseContentRefactor, "canary_check_retries", 1);
|
||||
}
|
||||
|
||||
base::TimeDelta PrefetchBlockUntilHeadTimeout(
|
||||
const PrefetchType& prefetch_type) {
|
||||
base::TimeDelta PrefetchBlockUntilHeadTimeout(const PrefetchType& prefetch_type,
|
||||
bool is_nav_prerender) {
|
||||
// Don't set a timeout for prerender because
|
||||
//
|
||||
// - The intention of prefetch ahead of prerender is not sending additional
|
||||
// fetch request. The options of the behavior of the timeout case are
|
||||
// 1. (Current behavior) Making prerender fail, or 2. Falling back to
|
||||
// network.
|
||||
// - 1 reduces the prerender activation rate.
|
||||
//
|
||||
// For more details, see
|
||||
// https://docs.google.com/document/d/1ZP7lYrtqZL9jC2xXieNY_UBMJL1sCrfmzTB8K6v4sD4/edit?resourcekey=0-fkbeQhkT3PhBb9FnnPgnZA&tab=t.wphan8fb23kr
|
||||
if (!features::kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout.Get() &&
|
||||
is_nav_prerender) {
|
||||
return base::Seconds(0);
|
||||
}
|
||||
|
||||
int timeout_in_milliseconds = 0;
|
||||
if (IsSpeculationRuleType(prefetch_type.trigger_type())) {
|
||||
switch (prefetch_type.GetEagerness()) {
|
||||
|
@ -100,7 +100,8 @@ int PrefetchCanaryCheckRetries();
|
||||
// The maximum amount of time to block until the head of a prefetch is received.
|
||||
// If the value is zero or less, then a navigation can be blocked indefinitely.
|
||||
CONTENT_EXPORT base::TimeDelta PrefetchBlockUntilHeadTimeout(
|
||||
const PrefetchType& prefetch_type);
|
||||
const PrefetchType& prefetch_type,
|
||||
bool is_nav_prerender);
|
||||
|
||||
// Gets the histogram suffix to use for the given eagerness parameter.
|
||||
CONTENT_EXPORT std::string GetPrefetchEagernessHistogramSuffix(
|
||||
|
@ -4444,7 +4444,7 @@ TEST_P(PrefetchServiceAlwaysBlockUntilHeadTest,
|
||||
std::string histogram_suffix =
|
||||
GetPrefetchEagernessHistogramSuffix(GetParam());
|
||||
base::TimeDelta block_until_head_timeout =
|
||||
PrefetchBlockUntilHeadTimeout(prefetch_type);
|
||||
PrefetchBlockUntilHeadTimeout(prefetch_type, /*is_nav_prerender=*/false);
|
||||
histogram_tester.ExpectTotalCount(
|
||||
base::StringPrintf(
|
||||
"PrefetchProxy.AfterClick.BlockUntilHeadDuration2NoBias.Served.%s",
|
||||
|
@ -41,6 +41,11 @@ const base::FeatureParam<size_t> kPrerender2FallbackBodySizeLimit{
|
||||
&kPrerender2FallbackPrefetchSpecRules, "kPrerender2FallbackBodySizeLimit",
|
||||
65536};
|
||||
|
||||
const base::FeatureParam<bool>
|
||||
kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout{
|
||||
&kPrerender2FallbackPrefetchSpecRules,
|
||||
"kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout", true};
|
||||
|
||||
BASE_FEATURE(kPrerender2NoVarySearch,
|
||||
"Prerender2NoVarySearch",
|
||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
||||
|
@ -38,6 +38,13 @@ CONTENT_EXPORT extern const base::FeatureParam<
|
||||
CONTENT_EXPORT extern const base::FeatureParam<size_t>
|
||||
kPrerender2FallbackBodySizeLimit;
|
||||
|
||||
// Controls whether `PrefetchMatchResolver` use timeout for prefetch ahead of
|
||||
// prerender. We are going not to use timeout as it makes prerender fail. For
|
||||
// more details, see
|
||||
// https://docs.google.com/document/d/1ZP7lYrtqZL9jC2xXieNY_UBMJL1sCrfmzTB8K6v4sD4/edit?resourcekey=0-fkbeQhkT3PhBb9FnnPgnZA&tab=t.wphan8fb23kr
|
||||
CONTENT_EXPORT extern const base::FeatureParam<bool>
|
||||
kPrerender2FallbackPrefetchUseBlockUntilHeadTimetout;
|
||||
|
||||
// This feature was used to launch Prerender2 support for No-Vary-Search header.
|
||||
// This work has finished and the old implementation was deleted. Now this flag
|
||||
// is just for injecting parameters through field trials as an umberella
|
||||
|
Reference in New Issue
Block a user